00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include PLATFORM_HEADER
00012 #include "error.h"
00013
00014 #ifdef NVM_RAM_EMULATION
00015
00016 static int16u calibrationData[32+2]={
00017 0xFFFF, 0xFFFF,
00018 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
00019 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
00020 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
00021 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
00022 };
00023
00024 int8u halCommonReadFromNvm(void *data, int32u offset, int16u length)
00025 {
00026 halCommonMemCopy(data, ((int8u *) calibrationData) + offset, length);
00027 return ST_SUCCESS;
00028 }
00029 int8u halCommonWriteToNvm(const void *data, int32u offset, int16u length)
00030 {
00031 halCommonMemCopy(((int8u *) calibrationData) + offset, data, length);
00032 return ST_SUCCESS;
00033 }
00034
00035 #else
00036
00037
00038 #include "hal/micro/cortexm3/flash.h"
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "hal/micro/cortexm3/nvm.h"
00048
00049
00050
00051
00052
00053 NO_STRIPPING __no_init VAR_AT_SEGMENT (const int8u nvmStorageLeft[NVM_DATA_SIZE_B], __NVM__);
00054 NO_STRIPPING __no_init VAR_AT_SEGMENT (const int8u nvmStorageRight[NVM_DATA_SIZE_B], __NVM__);
00055
00056 static int8u determineState(void)
00057 {
00058 int32u leftMgmt = *(int32u *)NVM_LEFT_PAGE;
00059 int32u rightMgmt = *(int32u *)NVM_RIGHT_PAGE;
00060 int8u state=0;
00061
00062 if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFFFF)) {
00063
00064
00065
00066
00067
00068
00069
00070 state = 4;
00071 } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFF00FFFF)) {
00072 state = 2;
00073 } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFF000000)) {
00074 state = 3;
00075 } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFFFF)) {
00076 state = 4;
00077 } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFF00)) {
00078 state = 5;
00079 } else if((leftMgmt==0xFF000000) && (rightMgmt==0xFFFFFF00)) {
00080 state = 6;
00081 } else if((leftMgmt==0xFF000000) && (rightMgmt==0xFFFF0000)) {
00082 state = 7;
00083 } else if((leftMgmt==0xFFFFFFFF) && (rightMgmt==0xFFFF0000)) {
00084 state = 8;
00085 } else if((leftMgmt==0xFFFFFF00) && (rightMgmt==0xFFFF0000)) {
00086 state = 9;
00087 } else if((leftMgmt==0xFFFFFF00) && (rightMgmt==0xFF000000)) {
00088 state = 10;
00089 } else {
00090
00091 state = 0;
00092 }
00093
00094 return state;
00095 }
00096
00097
00098 int8u halCommonReadFromNvm(void *data, int32u offset, int16u length)
00099 {
00100 int16u i;
00101 int16u *flash;
00102
00103 int16u *ram = (int16u*)data;
00104
00105
00106
00107 assert((NVM_LEFT_PAGE%MFB_PAGE_SIZE_B)==0);
00108 assert((NVM_RIGHT_PAGE%MFB_PAGE_SIZE_B)==0);
00109
00110 assert((offset&0x1)==0);
00111
00112 assert((length&0x1)==0);
00113
00114 assert(offset+length<NVM_DATA_SIZE_B);
00115
00116
00117 switch(determineState()) {
00118 case 1:
00119 case 2:
00120 case 3:
00121 case 4:
00122 case 9:
00123 case 10:
00124 flash = (int16u *)(NVM_LEFT_PAGE+offset);
00125 for(i=0;i<(length/2);i++) {
00126 ram[i] = flash[i];
00127 }
00128 break;
00129 case 5:
00130 case 6:
00131 case 7:
00132 case 8:
00133 flash = (int16u *)(NVM_RIGHT_PAGE+offset);
00134 for(i=0;i<(length/2);i++) {
00135 ram[i] = flash[i];
00136 }
00137 break;
00138 case 0:
00139 default:
00140
00141
00142
00143
00144
00145
00146
00147 for(i=0;i<(length/2);i++) {
00148 ram[i] = 0xFFFF;
00149 }
00150
00151
00152 return ST_ERR_FATAL;
00153 }
00154
00155 return ST_SUCCESS;
00156 }
00157
00158 int16u *halCommonGetAddressFromNvm(int32u offset)
00159 {
00160 int16u *flash;
00161
00162
00163
00164 assert((NVM_LEFT_PAGE%MFB_PAGE_SIZE_B)==0);
00165 assert((NVM_RIGHT_PAGE%MFB_PAGE_SIZE_B)==0);
00166
00167 assert((offset&0x1)==0);
00168
00169
00170 switch(determineState()) {
00171 case 1:
00172 case 2:
00173 case 3:
00174 case 4:
00175 case 9:
00176 case 10:
00177 flash = (int16u *)(NVM_LEFT_PAGE+offset);
00178 break;
00179 case 5:
00180 case 6:
00181 case 7:
00182 case 8:
00183 flash = (int16u *)(NVM_RIGHT_PAGE+offset);
00184 break;
00185 case 0:
00186 default:
00187
00188
00189 {
00190 int16u dummy = 0xFFFF;
00191 halCommonWriteToNvm(&dummy, 0, 2);
00192 flash = (int16u *)(NVM_LEFT_PAGE+offset);
00193 }
00194 }
00195
00196 return flash;
00197 }
00198
00199
00200 static int8u erasePage(int32u page)
00201 {
00202 StStatus status;
00203 int32u i, k;
00204 int32u address;
00205 int8u *flash;
00206
00207
00208
00209
00210
00211
00212 for(i=NVM_FLASH_PAGE_COUNT;i>0;i--) {
00213 address = (page+((i-1)*MFB_PAGE_SIZE_B));
00214 flash = (int8u *)address;
00215
00216
00217
00218 for(k=0;k<MFB_PAGE_SIZE_B;k++,flash++) {
00219 if(*flash != 0xFF) {
00220 status = halInternalFlashErase(MFB_PAGE_ERASE, address);
00221 if(status != ST_SUCCESS) {
00222 return status;
00223 }
00224
00225
00226 k=MFB_PAGE_SIZE_B;
00227 }
00228 }
00229 }
00230 return ST_SUCCESS;
00231 }
00232
00233
00234
00235 #define ERASE_PAGE(page) \
00236 do { \
00237 status = erasePage(page); \
00238 if(status != ST_SUCCESS) { \
00239 return status; \
00240 } \
00241 } while(0)
00242
00243
00244
00245
00246
00247 #define WRITE_DATA(destPage, srcPage, offset, length) \
00248 do { \
00249 \
00250 status = halInternalFlashWrite(destPage+NVM_MGMT_SIZE_B, \
00251 (int16u *)(srcPage+NVM_MGMT_SIZE_B), \
00252 (offset-NVM_MGMT_SIZE_B)/2); \
00253 if(status != ST_SUCCESS) { return status; } \
00254 \
00255 status = halInternalFlashWrite(destPage+offset, \
00256 ram, \
00257 (length)/2); \
00258 if(status != ST_SUCCESS) { return status; } \
00259 \
00260 status = halInternalFlashWrite(destPage+offset+length, \
00261 (int16u *)(srcPage+offset+length), \
00262 (NVM_DATA_SIZE_B- \
00263 length-offset- \
00264 NVM_MGMT_SIZE_B)/2); \
00265 if(status != ST_SUCCESS) { return status; } \
00266 } while(0)
00267
00268
00269
00270 #define WRITE_MGMT_16BITS(address, data) \
00271 do{ \
00272 int16u value = data; \
00273 status = halInternalFlashWrite((address), &value, 1); \
00274 if(status != ST_SUCCESS) { \
00275 return status; \
00276 } \
00277 } while(0)
00278
00279
00280 int8u halCommonWriteToNvm(const void *data, int32u offset, int16u length)
00281 {
00282 StStatus status;
00283 int8u state, exitState;
00284 int32u srcPage;
00285 int32u destPage;
00286
00287 int16u *ram = (int16u*)data;
00288
00289
00290
00291 assert((NVM_LEFT_PAGE%MFB_PAGE_SIZE_B)==0);
00292 assert((NVM_RIGHT_PAGE%MFB_PAGE_SIZE_B)==0);
00293
00294 assert((offset&0x1)==0);
00295
00296 assert((length&0x1)==0);
00297
00298 assert(offset+length<NVM_DATA_SIZE_B);
00299
00300
00301 state = determineState();
00302
00303 switch(state) {
00304 case 1:
00305 case 2:
00306 case 3:
00307 case 4:
00308 case 9:
00309 case 10:
00310 srcPage = NVM_LEFT_PAGE;
00311 destPage = NVM_RIGHT_PAGE;
00312 exitState = 7;
00313 break;
00314 case 5:
00315 case 6:
00316 case 7:
00317 case 8:
00318 srcPage = NVM_RIGHT_PAGE;
00319 destPage = NVM_LEFT_PAGE;
00320 exitState = 3;
00321 break;
00322 case 0:
00323 default:
00324
00325
00326
00327 state = 0;
00328 srcPage = NVM_RIGHT_PAGE;
00329 destPage = NVM_LEFT_PAGE;
00330 exitState = 3;
00331 break;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340 while(TRUE) {
00341 switch(state) {
00342 case 0:
00343
00344 ERASE_PAGE(srcPage);
00345 ERASE_PAGE(destPage);
00346 WRITE_DATA(destPage, srcPage, offset, length);
00347 WRITE_MGMT_16BITS(NVM_LEFT_PAGE+0, 0x0000);
00348 state=1;
00349 break;
00350 case 1:
00351 WRITE_MGMT_16BITS(NVM_RIGHT_PAGE+2, 0xFF00);
00352 state=2;
00353 break;
00354 case 2:
00355 WRITE_MGMT_16BITS(NVM_RIGHT_PAGE+0, 0x0000);
00356 state=3;
00357 break;
00358 case 3:
00359 if(exitState==3) {
00360 return ST_SUCCESS;
00361 }
00362 ERASE_PAGE(destPage);
00363 state=4;
00364 break;
00365 case 4:
00366 WRITE_DATA(destPage, srcPage, offset, length);
00367 WRITE_MGMT_16BITS(NVM_RIGHT_PAGE+0, 0xFF00);
00368 state=5;
00369 break;
00370 case 5:
00371 WRITE_MGMT_16BITS(NVM_LEFT_PAGE+2, 0xFF00);
00372 state=6;
00373 break;
00374 case 6:
00375 WRITE_MGMT_16BITS(NVM_RIGHT_PAGE+0, 0x0000);
00376 state=7;
00377 break;
00378 case 7:
00379 if(exitState==7) {
00380 return ST_SUCCESS;
00381 }
00382 ERASE_PAGE(destPage);
00383 state=8;
00384 break;
00385 case 8:
00386 WRITE_DATA(destPage, srcPage, offset, length);
00387 WRITE_MGMT_16BITS(NVM_LEFT_PAGE+0, 0xFF00);
00388 state=9;
00389 break;
00390 case 9:
00391 WRITE_MGMT_16BITS(NVM_RIGHT_PAGE+2, 0xFF00);
00392 state=10;
00393 break;
00394 case 10:
00395 WRITE_MGMT_16BITS(NVM_LEFT_PAGE+0, 0x0000);
00396 state=3;
00397 break;
00398 }
00399 }
00400 }
00401
00402 #endif // NVM_RAM_EMULATION