Hi. Here is my code.
uint32_t oftenWrittenDataInSectorOffset = 0x20;
uint32_t oftenWrittenDataSectorOffset = 0x1000;
uint32_t oftenWrittenDataFlashBaseAddress = 0x10000000;
uint32_t oftenWrittenDataCounter = 0;
uint32_t fewWrittenDataInSectorOffset = 0x40;
uint32_t fewWrittenDataSectorOffset = 0x1000;
uint32_t fewWrittenDataFlashBaseAddress = 0x10010000;
Whey I detect a power fail, I execute this function:
uint32_t writeDataOnFlash(uint32_t dest, uint32_t size){
int32_t checkSum = 0;
uint8_t oftenWrittenData[24] = {0};
uint64_t cast;
uint8_t *pData;
uint32_t ret;
if(size > 24){
//Size to large
return ERR_SIZE;
}
for(int i = size; i > 0; i--){
//read data and calculate checkSum
pData = (uint8_t *) ((dest-1) + i);
oftenWrittenData[i-1] = *pData;
checkSum += *pData;
}
pData = (uint8_t *) &cast;
for(int i = 0; i < 4; i++){
//counter write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenDataCounter))+i);
checkSum += *pData;
pData++;
}
for(int i = 0; i < 4; i++){
//first value write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write counter and first value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 4; i < 12; i++){
//write 2. value and 3. value to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write 2. value and 3. value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+8, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 12; i < 20; i++){
//write 4. value and 5. value to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write 4. value and 5. value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+16, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 20; i < 24; i++){
//6. value write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
for(int i = 0; i < 4; i++){
//checkSum write to cast variable
*pData = *(((unsigned char *)(&checkSum))+i);
pData++;
}
//write 6. value and checkSum on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+24, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
//get next free flash memory
getOftenWrittenDataFlashAddress();
return OK;
}
Sometimes I have no time to save the 6. value and the checkSum. My flash memory is in this case FF FF FF FF FF FF FF FF for the 6. value and the checksum.
When I make a reset, I execute this function:
When I try to read the checksum with a normal pointer I get an Bus Error. (readCheckSum = *pCounter;)
uint32_t readDataFromFlash(uint32_t dest, uint32_t size){
int32_t *pCounter;
uint8_t *pByteCounter;
int32_t lastEntry;
int32_t readCheckSum;
int32_t proveCheckSum = 0;
uint8_t *pDest = (uint8_t *) dest;
if(size > 24){
//try to read to much bytes from flash
return ERR_SIZE;
}
//last entry is next free flash address - offset of stored data
lastEntry = destOftenWrittenData - oftenWrittenDataInSectorOffset;
uint32_t nextValue = 0;
do{
//find right data
if(lastEntry == 0x0FFFFFE0){
//transition from first sector to last sector
lastEntry = 0x10000000;
pCounter = (int *) (lastEntry + (oftenWrittenDataInSectorOffset - 0x4));
readCheckSum = *pCounter;
if(readCheckSum == -1){
lastEntry = 0x1000FFE0;
}
}
//read checksum
pCounter = (int *) (lastEntry + (oftenWrittenDataInSectorOffset - 0x4));
readCheckSum = *pCounter; // Here I get the error!
if(readCheckSum == -1){
//data empty
proveCheckSum = 0;
lastEntry -= oftenWrittenDataInSectorOffset;
nextValue++;
continue;
}
//calculate checksum
for(int j = 0; j < 28; j++){
pByteCounter = (unsigned char *) (lastEntry + j);
proveCheckSum += *pByteCounter;
}
//found right data
if(readCheckSum == proveCheckSum){
//set next value to 128, so the do while reach the end
nextValue = 128;
}else{
proveCheckSum = 0;
}
lastEntry -= oftenWrittenDataInSectorOffset;
nextValue++;
}while(proveCheckSum != readCheckSum && nextValue < 128); //prove checksum; if all checksums (128) in sector wrong -> break
if(proveCheckSum == readCheckSum){
//checksum right -> read data
for(int i = 4; i < size+4; i++){
pByteCounter = (unsigned char *) ((lastEntry + oftenWrittenDataInSectorOffset)+i);
*(pDest + (i-4)) = *pByteCounter;
}
return OK;
}
return ERR_NO_VALID_DATA;
}