comparison Discovery/Src/externLogbookFlash.c @ 557:2702bfa7b177

Stabilityfix: Do not trust lastDiveLogID == 0 at startup: If dive settings are reset for some reason also the lastDiveLogID is set to 0. Most likly the consostency check will find a valid entry. But this entry might not be the last one => return an error value to trigger the find function. Calling "find" at every startup is normal behavior if TRUST_LOG_CONSISTENCY is not set and was default for a long time => low risk In addition a check of the header adresses has been added to identify a potential error while writing log samples
author Ideenmodellierer
date Thu, 12 Nov 2020 20:03:00 +0100
parents b1eee27cd02b
children bc6c90e20d9e
comparison
equal deleted inserted replaced
556:eb2060caca7d 557:2702bfa7b177
1399 { 1399 {
1400 uint8_t ret = 0; 1400 uint8_t ret = 0;
1401 uint8_t header1, header2; 1401 uint8_t header1, header2;
1402 uint8_t id; 1402 uint8_t id;
1403 convert_Type dataStart; 1403 convert_Type dataStart;
1404 convert_Type dataEnd;
1404 1405
1405 SSettings *settings = settingsGetPointer(); 1406 SSettings *settings = settingsGetPointer();
1406 id = settings->lastDiveLogId; 1407 id = settings->lastDiveLogId;
1407 1408
1408 actualAddress = HEADERSTART + (0x800 * id); 1409 if(settings->lastDiveLogId != 0) /* not trust LogID 0 which might be reset by a settings problem */
1409 ext_flash_read_block_start(); 1410 { /* ==> Find function will be called restoring the Id belonging to the latest sample */
1410 ext_flash_read_block(&header1, EF_HEADER); 1411 actualAddress = HEADERSTART + (0x800 * id);
1411 ext_flash_read_block(&header2, EF_HEADER); 1412 ext_flash_read_block_start();
1412 dataStart.u8bit.byteHigh = 0; 1413 ext_flash_read_block(&header1, EF_HEADER);
1413 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); 1414 ext_flash_read_block(&header2, EF_HEADER);
1414 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); 1415 ext_flash_read_block_stop();
1415 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); 1416 if((header1 == 0xFA) && (header2 == 0xFA)) /* Header is indicating the start of a dive */
1416 ext_flash_read_block_stop(); 1417 {
1417 if((header1 == 0xFA) && (header2 == 0xFA)) /* Header is indicating the start of a dive */ 1418 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;
1418 { 1419 ext_flash_read_block_start();
1419 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; 1420 ext_flash_read_block(&header1, EF_HEADER);
1420 ext_flash_read_block_start(); 1421 ext_flash_read_block(&header2, EF_HEADER);
1421 ext_flash_read_block(&header1, EF_HEADER); 1422 dataStart.u8bit.byteHigh = 0;
1422 ext_flash_read_block(&header2, EF_HEADER); 1423 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);
1423 ext_flash_read_block_stop(); 1424 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);
1424 if((header1 == 0xFA) && (header2 == 0xFA)) /* Secondary header was written at the end of a dive */ 1425 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);
1425 { 1426 dataEnd.u8bit.byteHigh = 0;
1426 ret = 1; /* => lastDiveLogID points to a valid dive entry */ 1427 ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER);
1427 } 1428 ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER);
1428 } 1429 ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER);
1430 ext_flash_read_block_stop();
1431
1432 if((header1 == 0xFA) && (header2 == 0xFA)) /* Secondary header was written at the end of a dive */
1433 {
1434 if(dataStart.u32bit < dataEnd.u32bit)
1435 {
1436 ret = 1; /* => lastDiveLogID points to a valid dive entry */
1437 }
1438 else /* check if address wrap is valid */
1439 {
1440 if(ext_flash_SampleOverrunValid())
1441 {
1442 ret = 1;
1443 }
1444 }
1445 }
1446 }
1447 }
1429 return ret; 1448 return ret;
1430 } 1449 }
1431 1450
1432 // =============================================================================== 1451 // ===============================================================================
1433 // ext_flash_repair_dive_log 1452 // ext_flash_repair_dive_log
2228 uint32_t curAddress, actualaddrbackup; 2247 uint32_t curAddress, actualaddrbackup;
2229 uint8_t tmpBuffer; 2248 uint8_t tmpBuffer;
2230 uint8_t emptyCellCnt = 0; 2249 uint8_t emptyCellCnt = 0;
2231 2250
2232 actualaddrbackup = actualAddress; 2251 actualaddrbackup = actualAddress;
2233 curAddress = SAMPLESTOP - 20; /* check the last 10 bytes of the last sample sector */ 2252 curAddress = SAMPLESTOP - 20; /* check the last 20 bytes of the last sample sector */
2234 actualAddress = curAddress; 2253 actualAddress = curAddress;
2235 ext_flash_read_block_start(); 2254 ext_flash_read_block_start();
2236 while(actualAddress < SAMPLESTOP) 2255 while(actualAddress < SAMPLESTOP)
2237 { 2256 {
2238 tmpBuffer = read_spi(HOLDCS);/* read data */ 2257 tmpBuffer = read_spi(HOLDCS);/* read data */
2250 } 2269 }
2251 actualAddress = actualaddrbackup; 2270 actualAddress = actualaddrbackup;
2252 return jumpvalid; 2271 return jumpvalid;
2253 } 2272 }
2254 2273
2255 uint32_t ext_flash_AnalyseSampleBuffer(char *pstrResult) 2274 uint32_t ext_flash_AnalyseSampleBuffer()
2256 { 2275 {
2257 uint8_t sectorState[16]; /* samples are stored in 16 sector / 64k each */ 2276 uint8_t sectorState[192]; /* samples are stored in 192 sector / 64k each */
2258 uint32_t curAddress = SAMPLESTART; 2277 uint32_t curAddress = SAMPLESTART;
2259 uint8_t curSector = 0; 2278 uint8_t curSector = 0;
2260 uint8_t samplebuffer[10]; 2279 uint8_t samplebuffer[10];
2261 uint32_t actualAddressBackup = actualAddress; 2280 uint32_t actualAddressBackup = actualAddress;
2262 uint8_t emptyCellCnt = 0; 2281 uint8_t emptyCellCnt = 0;
2263 uint32_t i = 0; 2282 uint32_t i = 0;
2264 uint8_t startedSectors = 0; 2283 uint8_t startedSectors = 0;
2265 uint8_t lastSectorInuse = 0; 2284 uint8_t lastSectorInuse = 0;
2266 2285
2267 /* check if a sector is used till its end */ 2286 /* check if a sector is used till its end */
2268 for(curSector = 0; curSector < 16; curSector++) 2287 for(curSector = 0; curSector < 192; curSector++)
2269 { 2288 {
2270 sectorState[curSector] = 0; 2289 sectorState[curSector] = 0;
2271 emptyCellCnt = 0; 2290 emptyCellCnt = 0;
2272 curAddress = SAMPLESTART + (curSector * 0x10000); /* set address to begin of sector and check if it is used */ 2291 curAddress = SAMPLESTART + (curSector * 0x10000); /* set address to begin of sector and check if it is used */
2273 actualAddress = curAddress; 2292 actualAddress = curAddress;
2302 { 2321 {
2303 sectorState[curSector] |= SECTOR_INUSE; /* will become SECTOR_EMPTY if start is NOTUSED */ 2322 sectorState[curSector] |= SECTOR_INUSE; /* will become SECTOR_EMPTY if start is NOTUSED */
2304 } 2323 }
2305 } 2324 }
2306 2325
2307 for(i=0;i<16;i++) 2326 for(i=0;i<192;i++)
2308 { 2327 {
2309 if( sectorState[i] == SECTOR_INUSE) 2328 if( sectorState[i] == SECTOR_INUSE)
2310 { 2329 {
2311 startedSectors++; 2330 startedSectors++;
2312 lastSectorInuse = i; 2331 lastSectorInuse = i;
2313 } 2332 }
2314 *(pstrResult+i) = sectorState[i] + 48;
2315 } 2333 }
2316 2334
2317 if(startedSectors > 1) /* more than one sector is in used => ring buffer corrupted */ 2335 if(startedSectors > 1) /* more than one sector is in used => ring buffer corrupted */
2318 { 2336 {
2319 if(startedSectors == 2) /* only fix issue if only two sectors are in used. Otherwise fixing will cause more worries than help */ 2337 if(startedSectors == 2) /* only fix issue if only two sectors are in used. Otherwise fixing will cause more worries than help */
2341 actualPointerSample = actualAddress; 2359 actualPointerSample = actualAddress;
2342 2360
2343 closeSectorAddress = settingsGetPointer()->logFlashNextSampleStartAddress & 0xFFFF0000; 2361 closeSectorAddress = settingsGetPointer()->logFlashNextSampleStartAddress & 0xFFFF0000;
2344 closeSectorAddress += 0xFFF5; /* to be used once next time a dive is logged. Needed because NextSampleID is derived at every startup */ 2362 closeSectorAddress += 0xFFF5; /* to be used once next time a dive is logged. Needed because NextSampleID is derived at every startup */
2345 settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample; /* store new position to be used for next dive */ 2363 settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample; /* store new position to be used for next dive */
2364 ext_flash_CloseSector();
2346 } 2365 }
2347 } 2366 }
2348 actualAddress = actualAddressBackup; 2367 actualAddress = actualAddressBackup;
2349 *(pstrResult+i) = 0;
2350 return startedSectors; 2368 return startedSectors;
2351 } 2369 }
2352 2370
2353 uint32_t ext_flash_read_profilelength_small_header(uint32_t smallHeaderAddr) 2371 uint32_t ext_flash_read_profilelength_small_header(uint32_t smallHeaderAddr)
2354 { 2372 {