请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:MSP430F233 #include "data.h"
#include "ks0108.h"
#include "Flash.h"
// these defines need changing as we add or remove data elements
// they must be even values rounded up!
#define CAL_DATA_LENGTH 24
#define PERSISTENT_DATA_LENGTH 6
#define MEM_POINTER_LENGTH 4
extern Fonts fonts;
// split up save structures as may have different save times.
// save/load persistent tested with infoSegB
void Data_Save_Persistent(PersistentData* pd, MemPointers* mp){
uint8_t dataBuf[PERSISTENT_DATA_LENGTH];
uint8_t errBuf[PERSISTENT_DATA_LENGTH];
uint8_t ii;
uint8_t fails;
uint8_t testFail = 0x01;
// initalize arrays to 0xFF
for(ii = 0; ii < PERSISTENT_DATA_LENGTH; ii++){
dataBuf[ii] = 0xFF;
errBuf[ii] = 0xFF;
}
// 16 bit fields
Split_16(pd->trip1, dataBuf, 0);
Split_16(pd->tankLevel1, dataBuf, 2);
Split_16(pd->tankLevel2, dataBuf, 4);
do{
fails = 0;
// erase flash
Flash_Erase((uint16_t*)mp->persistentDataPtr);
Flash_Read(errBuf, (uint16_t*)mp->persistentDataPtr, PERSISTENT_DATA_LENGTH);
/* failure simulation test
if(testFail == 0x01){
fails++;
testFail--;
GLCD_Debug_Print("fail test per", font);
__delay_cycles(200000);
} */
for(ii = 0; ii < PERSISTENT_DATA_LENGTH; ii++){
if(errBuf[ii] != 0xff){
fails++;
}
}
// copy arrays for error test
for(ii = 0; ii < PERSISTENT_DATA_LENGTH; ii++){
errBuf[ii] = dataBuf[ii];
}
// save persistent data to infoSegB
Flash_Write(dataBuf, (uint16_t*)mp->persistentDataPtr, PERSISTENT_DATA_LENGTH);
// check saved data against written data
Flash_Read(errBuf, (uint16_t*)mp->persistentDataPtr, PERSISTENT_DATA_LENGTH);
for(ii = 0; ii < PERSISTENT_DATA_LENGTH; ii++){
if(errBuf[ii] != dataBuf[ii]){
fails++;
}
}
if(fails > 0){
if(mp->persistentDataPtr + PERSISTENT_DATA_LENGTH < INFO_SEG_A){
mp->persistentDataPtr += PERSISTENT_DATA_LENGTH; // add length of persistent data to the mem pointer
}
else{
// restore the first address of infoSegB
mp->persistentDataPtr = INFO_SEG_B;
// add half the length of byte array to stagger over memory in case of one bad cell
mp->persistentDataPtr += (PERSISTENT_DATA_LENGTH >> 0x01);
}
// save this new memory pointer
Data_Save_Mem_Pointers(mp);
}
}while(fails > 0);
}
void Data_Load_Persistent(PersistentData* pd, MemPointers* mp){
uint8_t dataBuf[PERSISTENT_DATA_LENGTH];
Flash_Read(dataBuf, (uint16_t*)mp->persistentDataPtr, PERSISTENT_DATA_LENGTH); // read in data from flash
pd->trip1 = Merge_16(dataBuf, 0);
pd->tankLevel1 = Merge_16(dataBuf, 2);
pd->tankLevel2 = Merge_16(dataBuf, 4);
}
// just save cal data, use after calibration changes.
void Data_Save_Cal(CalData* cd, MemPointers* mp){
uint8_t dataBuf[CAL_DATA_LENGTH];
uint8_t errBuf[CAL_DATA_LENGTH];
uint8_t ii;
uint8_t fails;
uint8_t testFail = 0x01;
bool flags[8]= {0,0,0,0,0,0,0,0};
// initalize arrays to 0xFF
for(ii = 0; ii < CAL_DATA_LENGTH; ii++){
dataBuf[ii] = 0xFF;
errBuf[ii] = 0xFF;
}
// save bits
flags[0] = cd->lang;
flags[1] = cd->gpsDisable;
flags[2] = cd->backlightDim;
flags[3] = cd->singleDualProduct;
// save bytes to buffer
dataBuf[0] = Merge_Flags(flags);
dataBuf[1] = cd->product1Rate;
dataBuf[2] = cd->product2Rate;
dataBuf[3] = cd->rate1Units;
dataBuf[4] = cd->rate2Units;
dataBuf[5] = cd->rate1Span;
dataBuf[6] = cd->rate2Span;
dataBuf[7] = cd->pwm1Min;
dataBuf[8] = cd->pwm1Max;
dataBuf[9] = cd->pwm2Min;
dataBuf[10] = cd->pwm2Max;
dataBuf[11] = cd->primeSpeed;
dataBuf[12] = cd->slowSpeed;
dataBuf[13] = cd->holdSpeed;
dataBuf[14] = cd->simulateSpeed;
// save multibytes to buffer
Split_16(cd->boomWidth, dataBuf, 15);
Split_16(cd->PPL1, dataBuf, 17);
Split_16(cd->PPL2, dataBuf, 19);
Split_16(cd->wheelCoEff, dataBuf, 21);
do{
fails = 0;
Flash_Erase((uint16_t*)mp->calDataPtr);
Flash_Read(errBuf, (uint16_t*)mp->calDataPtr, CAL_DATA_LENGTH);
/* Debug failure test
if(testFail == 0x01){
fails++;
testFail--;
GLCD_Debug_Print("fail test cal", font);
__delay_cycles(20000000);
}
*/
for(ii = 0; ii < CAL_DATA_LENGTH; ii++){
if(errBuf[ii] != 0xFF){
fails++;
}
}
// copy arrays for error test
for(ii = 0; ii < CAL_DATA_LENGTH; ii++){
errBuf[ii] = dataBuf[ii];
}
// save calData data to infoSegC
Flash_Write(dataBuf, (uint16_t*)mp->calDataPtr, CAL_DATA_LENGTH);
// check saved data against written data
Flash_Read(errBuf, (uint16_t*)mp->calDataPtr, CAL_DATA_LENGTH);
for(ii = 0; ii < CAL_DATA_LENGTH; ii++){
if(errBuf[ii] != dataBuf[ii]){
fails++;
}
}
if(fails > 0){
if(mp->calDataPtr + CAL_DATA_LENGTH < INFO_SEG_B){
mp->calDataPtr += CAL_DATA_LENGTH; // add length of cal data to the mem pointer
}
else{
// restore to the first memory address of infoSegC
mp->calDataPtr = INFO_SEG_C;
// add half of calData byte array length
mp->calDataPtr += (CAL_DATA_LENGTH >> 0x01);
}
// save new pointer
Data_Save_Mem_Pointers(mp);
}
}while(fails > 0);
}
// create calibration data default
// these values just for testing
void Data_Cal_Default(CalData* cd){
// bits
cd->lang = 0;
cd->gpsDisable = 1;
cd->backlightDim = 1;
cd->singleDualProduct = 0;
// bytes
cd->product1Rate = 0x00;
cd->product2Rate = 0x01;
cd->rate1Units = 0x02;
cd->rate2Units = 0x03;
cd->rate1Span = 0x04;
cd->rate2Span = 0x05;
cd->pwm1Min = 0x06;
cd->pwm1Max = 0x07;
cd->pwm2Min = 0x08;
cd->pwm2Max = 0x09;
cd->primeSpeed = 0x0A;
cd->slowSpeed = 0x0B;
cd->holdSpeed = 0x0C;
cd->simulateSpeed = 0x0D;
cd->boomWidth = 0x0E;
cd->PPL1 = 0x0F;
cd->PPL2 = 0x10;
cd->wheelCoEff = 0x11;
}
// function to just load calibration data
void Data_Load_Cal(CalData* cd, MemPointers* mp){
uint8_t dataBuf[CAL_DATA_LENGTH];
bool flags[8];
Flash_Read(dataBuf, (uint16_t*)mp->calDataPtr, CAL_DATA_LENGTH); // read in data from flash
// split bits into bool array
Split_Flags(flags, dataBuf[0]);
// set bits
cd->lang = flags[0];
cd->gpsDisable = flags[1];
cd->backlightDim = flags[2];
cd->singleDualProduct = flags[3];
// set bytes
cd->product1Rate = dataBuf[1];
cd->product2Rate = dataBuf[2];
cd->rate1Units = dataBuf[3];
cd->rate2Units = dataBuf[4];
cd->rate1Span = dataBuf[5];
cd->rate2Span = dataBuf[6];
cd->pwm1Min = dataBuf[7];
cd->pwm1Max = dataBuf[8];
cd->pwm2Min = dataBuf[9];
cd->pwm2Max = dataBuf[10];
cd->primeSpeed = dataBuf[11];
cd->slowSpeed = dataBuf[12];
cd->holdSpeed = dataBuf[13];
cd->simulateSpeed = dataBuf[14];
// multi bytes
cd->boomWidth = Merge_16(dataBuf, 15);
cd->PPL1 = Merge_16(dataBuf, 17);
cd->PPL2 = Merge_16(dataBuf, 19);
cd->wheelCoEff = Merge_16(dataBuf, 21);
}
void Data_Default_Mem_Pointers(MemPointers* mp){
mp->calDataPtr = INFO_SEG_C;
mp->persistentDataPtr = INFO_SEG_B;
}
void Data_Load_Mem_Pointers(MemPointers* mp){
uint8_t dataBuf[MEM_POINTER_LENGTH];
Flash_Read(dataBuf, (uint16_t*)INFO_SEG_D, MEM_POINTER_LENGTH); // read in data from flash
mp->persistentDataPtr = Merge_16(dataBuf, 0);
mp->calDataPtr = Merge_16(dataBuf, 2);
}
void Data_Save_Mem_Pointers(MemPointers* mp){
uint8_t dataBuf[MEM_POINTER_LENGTH];
uint8_t errBuf[MEM_POINTER_LENGTH];
uint8_t ii, jj = 0;
uint8_t fails;
Split_16(mp->persistentDataPtr, dataBuf, 0);
Split_16(mp->calDataPtr, dataBuf, 2);
// loop over this while loop a maximum of 100 times
// to save from destroying memory in case of infinite loop?
do{
fails = 0;
Flash_Erase((uint16_t*)INFO_SEG_D);
Flash_Read(errBuf, (uint16_t*)INFO_SEG_D, MEM_POINTER_LENGTH);
for(ii = 0; ii < MEM_POINTER_LENGTH; ii++){
if(errBuf[ii] != 0xFF){
fails++;
}
}
// save memPointer data to infoSegD
Flash_Write(dataBuf, (uint16_t*)INFO_SEG_D, MEM_POINTER_LENGTH);
// check saved data against written data
Flash_Read(errBuf, (uint16_t*)INFO_SEG_D, MEM_POINTER_LENGTH);
for(ii = 0; ii < MEM_POINTER_LENGTH; ii++){
if(errBuf[ii] != dataBuf[ii]){
fails++;
}
}
jj++;
}
while(fails > 0 && jj < 100);
if(fails > 0){
// this is the main failure point.
// if the memory pointers can't be saved to 0x01000 and 0x01001
// due to bad cells I'm not sure how to recover from that.
// erases and writes to this segment only occur on failure of the other
// segments
}
}
// load all data
void Data_Load(MemPointers* mp, CalData* cd, PersistentData* pd){
Data_Load_Mem_Pointers(mp);
Data_Load_Persistent(pd, mp);
Data_Load_Cal(cd, mp);
}
// helper functions
void Split_Flags(bool outFlags[], uint8_t flagArray){
uint8_t ii;
for(ii = 0; ii < 8; ii++){
outFlags[ii] = (flagArray & (1<<ii)) != 0;
}
}
uint8_t Merge_Flags(bool inFlags[]){
uint8_t ii;
uint8_t result = 0x00;
for(ii = 0; ii < 8; ii++){
if(inFlags[ii]){
result |= 0x01 << ii;
}
}
return result;
}
void Split_16(uint16_t input, uint8_t dataBuf[], uint8_t index){
dataBuf[index] = (uint8_t)(input >> 0x08);
index++;
dataBuf[index] = (uint8_t)((input << 0x08) >> 0x08);
}
uint16_t Merge_16(uint8_t* dataBuf, uint8_t index){
uint16_t result = 0x0000;
result = dataBuf[index];
result <<= 0x08;
index++;
result += dataBuf[index];
return result;
}
// debug functions:
