comparison Discovery/Src/logbook.c @ 411:e908b894f107 Improment_NVM

Bugfix: Limit log length in case of corrupted sample storage: In case of a sample address reset the header would have a smaler end address as the start address. As result the length becomes very long and download e.g. via Subsurface, would seem to hang. To solve this the number of sample bytes in this use case has been limited. Tested with subsurface only. After change dowload of logs is possible again. Nevertheless the sampledata will be lost. Minor change: "header" was used as global as well as as local variable => changed name for global variant to gheader.
author ideenmodellierer
date Mon, 13 Jan 2020 20:27:57 +0100
parents 8e62f4701676
children 514e6269256f
comparison
equal deleted inserted replaced
410:f9458e979154 411:e908b894f107
62 #define NUM_GASES 5 62 #define NUM_GASES 5
63 63
64 #define LOGBOOK_VERSION (0x30) 64 #define LOGBOOK_VERSION (0x30)
65 #define LOGBOOK_VERSION_OSTC3 (0x24) 65 #define LOGBOOK_VERSION_OSTC3 (0x24)
66 66
67 #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */
68
67 typedef struct /* don't forget to adjust void clear_divisor(void) */ 69 typedef struct /* don't forget to adjust void clear_divisor(void) */
68 { 70 {
69 uint8_t temperature; 71 uint8_t temperature;
70 uint8_t deco_ndl; 72 uint8_t deco_ndl;
71 uint8_t gradientFactor; 73 uint8_t gradientFactor;
76 } SDivisor; 78 } SDivisor;
77 79
78 /* Exported variables --------------------------------------------------------*/ 80 /* Exported variables --------------------------------------------------------*/
79 81
80 /* Private variables ---------------------------------------------------------*/ 82 /* Private variables ---------------------------------------------------------*/
81 static SLogbookHeader header; 83 static SLogbookHeader gheader;
82 static SLogbookHeaderOSTC3 headerOSTC3; 84 static SLogbookHeaderOSTC3 headerOSTC3;
83 static SLogbookHeaderOSTC3compact headerOSTC3compact; 85 static SLogbookHeaderOSTC3compact headerOSTC3compact;
84 static SSmallHeader smallHeader; 86 static SSmallHeader smallHeader;
85 static SDivisor divisor; 87 static SDivisor divisor;
86 static SDivisor divisorBackup; 88 static SDivisor divisorBackup;
97 99
98 /* Exported functions --------------------------------------------------------*/ 100 /* Exported functions --------------------------------------------------------*/
99 101
100 void logbook_EndDive(void) 102 void logbook_EndDive(void)
101 { 103 {
102 ext_flash_close_new_dive_log((uint8_t*) &header); 104 ext_flash_close_new_dive_log((uint8_t*) &gheader);
103 } 105 }
104 106
105 107
106 // =============================================================================== 108 // ===============================================================================
107 // logbook_last_totalDiveCount 109 // logbook_last_totalDiveCount
134 * 136 *
135 * @return SLogbookHeader*: 137 * @return SLogbookHeader*:
136 */ 138 */
137 SLogbookHeader* logbook_getCurrentHeader(void) 139 SLogbookHeader* logbook_getCurrentHeader(void)
138 { 140 {
139 return &header; 141 return &gheader;
140 } 142 }
141 143
142 /** 144 /**
143 ****************************************************************************** 145 ******************************************************************************
144 * @brief logbook_getNumberOfHeaders. / 146 * @brief logbook_getNumberOfHeaders. /
196 RTC_DateTypeDef Sdate; 198 RTC_DateTypeDef Sdate;
197 RTC_TimeTypeDef Stime; 199 RTC_TimeTypeDef Stime;
198 200
199 for(int i = 0; i < sizeof(SLogbookHeader); i++) 201 for(int i = 0; i < sizeof(SLogbookHeader); i++)
200 { 202 {
201 ((uint8_t*)(&header))[i] = 0; 203 ((uint8_t*)(&gheader))[i] = 0;
202 } 204 }
203 header.diveHeaderStart = 0xFAFA; 205 gheader.diveHeaderStart = 0xFAFA;
204 header.diveHeaderEnd = 0xFBFB; 206 gheader.diveHeaderEnd = 0xFBFB;
205 header.samplingRate = 2; 207 gheader.samplingRate = 2;
206 if(pInfo->diveSettings.diveMode == DIVEMODE_OC) 208 if(pInfo->diveSettings.diveMode == DIVEMODE_OC)
207 { 209 {
208 for(int i = 0; i < 5; i++) 210 for(int i = 0; i < 5; i++)
209 { 211 {
210 header.gasordil[i].oxygen_percentage = pSettings->gas[i+1].oxygen_percentage; 212 gheader.gasordil[i].oxygen_percentage = pSettings->gas[i+1].oxygen_percentage;
211 header.gasordil[i].helium_percentage = pSettings->gas[i+1].helium_percentage; 213 gheader.gasordil[i].helium_percentage = pSettings->gas[i+1].helium_percentage;
212 header.gasordil[i].note.uw = pSettings->gas[i+1].note.uw; 214 gheader.gasordil[i].note.uw = pSettings->gas[i+1].note.uw;
213 header.gasordil[i].depth_meter = pSettings->gas[i+1].depth_meter; 215 gheader.gasordil[i].depth_meter = pSettings->gas[i+1].depth_meter;
214 } 216 }
215 } 217 }
216 else 218 else
217 { 219 {
218 for(int i = 0; i < 5; i++) 220 for(int i = 0; i < 5; i++)
219 { 221 {
220 header.gasordil[i].oxygen_percentage = pSettings->gas[i+6].oxygen_percentage; 222 gheader.gasordil[i].oxygen_percentage = pSettings->gas[i+6].oxygen_percentage;
221 header.gasordil[i].helium_percentage = pSettings->gas[i+6].helium_percentage; 223 gheader.gasordil[i].helium_percentage = pSettings->gas[i+6].helium_percentage;
222 header.gasordil[i].note.uw = pSettings->gas[i+6].note.uw; 224 gheader.gasordil[i].note.uw = pSettings->gas[i+6].note.uw;
223 header.gasordil[i].depth_meter = pSettings->gas[i+6].depth_meter; 225 gheader.gasordil[i].depth_meter = pSettings->gas[i+6].depth_meter;
224 } 226 }
225 227
226 for(int i = 0; i < 5; i++) 228 for(int i = 0; i < 5; i++)
227 { 229 {
228 header.setpoint[i].setpoint_cbar = pSettings->setpoint[i+1].setpoint_cbar; 230 gheader.setpoint[i].setpoint_cbar = pSettings->setpoint[i+1].setpoint_cbar;
229 header.setpoint[i].depth_meter = pSettings->setpoint[i+1].depth_meter; 231 gheader.setpoint[i].depth_meter = pSettings->setpoint[i+1].depth_meter;
230 } 232 }
231 } 233 }
232 // header.gasordil[pInfo->lifeData.actualGas.GasIdInSettings].depth_meter = 0; 234 // header.gasordil[pInfo->lifeData.actualGas.GasIdInSettings].depth_meter = 0;
233 235
234 translateDate(pInfo->lifeData.dateBinaryFormat, &Sdate); 236 translateDate(pInfo->lifeData.dateBinaryFormat, &Sdate);
235 translateTime(pInfo->lifeData.timeBinaryFormat, &Stime); 237 translateTime(pInfo->lifeData.timeBinaryFormat, &Stime);
236 header.dateYear = Sdate.Year; 238 gheader.dateYear = Sdate.Year;
237 header.dateMonth = Sdate.Month; 239 gheader.dateMonth = Sdate.Month;
238 header.dateDay = Sdate.Date; 240 gheader.dateDay = Sdate.Date;
239 header.timeHour = Stime.Hours; 241 gheader.timeHour = Stime.Hours;
240 header.timeMinute = Stime.Minutes; 242 gheader.timeMinute = Stime.Minutes;
241 header.cnsAtBeginning = (uint16_t)pInfo->lifeData.cns; 243 gheader.cnsAtBeginning = (uint16_t)pInfo->lifeData.cns;
242 header.surfacePressure_mbar = (uint16_t)(pInfo->lifeData.pressure_surface_bar * 1000); 244 gheader.surfacePressure_mbar = (uint16_t)(pInfo->lifeData.pressure_surface_bar * 1000);
243 header.firmwareVersionHigh = firmwareVersion_16bit_high(); 245 gheader.firmwareVersionHigh = firmwareVersion_16bit_high();
244 header.firmwareVersionLow = firmwareVersion_16bit_low(); 246 gheader.firmwareVersionLow = firmwareVersion_16bit_low();
245 header.logbookProfileVersion = LOGBOOK_VERSION; 247 gheader.logbookProfileVersion = LOGBOOK_VERSION;
246 header.salinity = pSettings->salinity; 248 gheader.salinity = pSettings->salinity;
247 header.diveNumber = pSettings->totalDiveCounter; 249 gheader.diveNumber = pSettings->totalDiveCounter;
248 header.personalDiveCount = pSettings->personalDiveCount; 250 gheader.personalDiveCount = pSettings->personalDiveCount;
249 251
250 header.diveMode = pInfo->diveSettings.diveMode; 252 gheader.diveMode = pInfo->diveSettings.diveMode;
251 header.CCRmode = pInfo->diveSettings.CCR_Mode; 253 gheader.CCRmode = pInfo->diveSettings.CCR_Mode;
252 header.lastDecostop_m = pSettings->last_stop_depth_meter; 254 gheader.lastDecostop_m = pSettings->last_stop_depth_meter;
253 255
254 if(pInfo->diveSettings.deco_type.ub.standard == GF_MODE) 256 if(pInfo->diveSettings.deco_type.ub.standard == GF_MODE)
255 { 257 {
256 header.decoModel = 1; 258 gheader.decoModel = 1;
257 header.gfLow_or_Vpm_conservatism = pInfo->diveSettings.gf_low; 259 gheader.gfLow_or_Vpm_conservatism = pInfo->diveSettings.gf_low;
258 header.gfHigh = pInfo->diveSettings.gf_high; 260 gheader.gfHigh = pInfo->diveSettings.gf_high;
259 } 261 }
260 else 262 else
261 { 263 {
262 header.decoModel = 2; 264 gheader.decoModel = 2;
263 header.gfLow_or_Vpm_conservatism = pInfo->diveSettings.vpm_conservatism; 265 gheader.gfLow_or_Vpm_conservatism = pInfo->diveSettings.vpm_conservatism;
264 header.gfHigh = 0; 266 gheader.gfHigh = 0;
265 } 267 }
266 268
267 memcpy(header.n2Compartments, pInfo->lifeData.tissue_nitrogen_bar, 64); 269 memcpy(gheader.n2Compartments, pInfo->lifeData.tissue_nitrogen_bar, 64);
268 memcpy(header.heCompartments, pInfo->lifeData.tissue_helium_bar, 64); 270 memcpy(gheader.heCompartments, pInfo->lifeData.tissue_helium_bar, 64);
269 271
270 logbook_SetCompartmentDesaturation(pInfo); 272 logbook_SetCompartmentDesaturation(pInfo);
271 273
272 ext_flash_start_new_dive_log_and_set_actualPointerSample((uint8_t*)&header); 274 ext_flash_start_new_dive_log_and_set_actualPointerSample((uint8_t*)&gheader);
273 275
274 smallHeader.profileLength[0] = 0xFF; 276 smallHeader.profileLength[0] = 0xFF;
275 smallHeader.profileLength[1] = 0xFF; 277 smallHeader.profileLength[1] = 0xFF;
276 smallHeader.profileLength[2] = 0xFF; 278 smallHeader.profileLength[2] = 0xFF;
277 smallHeader.samplingRate_seconds = 2; 279 smallHeader.samplingRate_seconds = 2;
1174 if(min_temperature_float_celsius > pStateReal->lifeData.temperature_celsius) 1176 if(min_temperature_float_celsius > pStateReal->lifeData.temperature_celsius)
1175 min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius; 1177 min_temperature_float_celsius = pStateReal->lifeData.temperature_celsius;
1176 tickstart = lasttick; 1178 tickstart = lasttick;
1177 if((bDiveMode == 1) && (pStateReal->lifeData.dive_time_seconds >= pSettings->divetimeToCreateLogbook)) 1179 if((bDiveMode == 1) && (pStateReal->lifeData.dive_time_seconds >= pSettings->divetimeToCreateLogbook))
1178 { 1180 {
1179 ext_flash_create_new_dive_log((uint8_t*)&header); 1181 ext_flash_create_new_dive_log((uint8_t*)&gheader);
1180 /** save settings 1182 /** save settings
1181 * with new lastDiveLogId and time and day 1183 * with new lastDiveLogId and time and day
1182 */ 1184 */
1183 pSettings->personalDiveCount++; 1185 pSettings->personalDiveCount++;
1184 if(pSettings->logbookOffset) 1186 if(pSettings->logbookOffset)
1199 logbook_SetAverageDepth(pStateReal->lifeData.average_depth_meter); 1201 logbook_SetAverageDepth(pStateReal->lifeData.average_depth_meter);
1200 logbook_SetMinTemperature(min_temperature_float_celsius); 1202 logbook_SetMinTemperature(min_temperature_float_celsius);
1201 logbook_SetMaxCNS(pStateReal->lifeData.cns); 1203 logbook_SetMaxCNS(pStateReal->lifeData.cns);
1202 logbook_SetCompartmentDesaturation(pStateReal); 1204 logbook_SetCompartmentDesaturation(pStateReal);
1203 logbook_SetLastStop(pStateReal->diveSettings.last_stop_depth_bar); 1205 logbook_SetLastStop(pStateReal->diveSettings.last_stop_depth_bar);
1204 header.batteryVoltage = pStateReal->lifeData.battery_voltage * 1000; 1206 gheader.batteryVoltage = pStateReal->lifeData.battery_voltage * 1000;
1205 logbook_EndDive(); 1207 logbook_EndDive();
1206 bDiveMode = 0; 1208 bDiveMode = 0;
1207 } else 1209 } else
1208 { 1210 {
1209 ext_flash_enable_protection(); 1211 ext_flash_enable_protection();
1240 header.dateDay = Sdate.Date; 1242 header.dateDay = Sdate.Date;
1241 header.timeHour = Stime.Hours; 1243 header.timeHour = Stime.Hours;
1242 header.timeMinute = Stime.Minutes; 1244 header.timeMinute = Stime.Minutes;
1243 */ 1245 */
1244 /// 160315 Quick fix for empty date problem 1246 /// 160315 Quick fix for empty date problem
1245 if((!(header.dateYear)) || (!(header.dateMonth)) || (!(header.dateDay))) 1247 if((!(gheader.dateYear)) || (!(gheader.dateMonth)) || (!(gheader.dateDay)))
1246 { 1248 {
1247 translateDate(pStateReal->lifeData.dateBinaryFormat, &Sdate); 1249 translateDate(pStateReal->lifeData.dateBinaryFormat, &Sdate);
1248 translateTime(pStateReal->lifeData.timeBinaryFormat, &Stime); 1250 translateTime(pStateReal->lifeData.timeBinaryFormat, &Stime);
1249 1251
1250 header.dateYear = Sdate.Year; 1252 gheader.dateYear = Sdate.Year;
1251 header.dateMonth = Sdate.Month; 1253 gheader.dateMonth = Sdate.Month;
1252 header.dateDay = Sdate.Date; 1254 gheader.dateDay = Sdate.Date;
1253 1255
1254 time1_u32 = (uint32_t)header.timeMinute + (uint32_t)(header.timeHour * 60); 1256 time1_u32 = (uint32_t)gheader.timeMinute + (uint32_t)(gheader.timeHour * 60);
1255 time2_u32 = (uint32_t)Stime.Minutes + (uint32_t)(Stime.Hours * 60); 1257 time2_u32 = (uint32_t)Stime.Minutes + (uint32_t)(Stime.Hours * 60);
1256 if(time2_u32 < time1_u32) 1258 if(time2_u32 < time1_u32)
1257 { 1259 {
1258 if(header.dateDay > 1) 1260 if(gheader.dateDay > 1)
1259 { 1261 {
1260 header.dateDay -= 1; 1262 gheader.dateDay -= 1;
1261 } 1263 }
1262 else 1264 else
1263 { 1265 {
1264 header.dateMonth --; 1266 gheader.dateMonth --;
1265 if(!header.dateMonth) 1267 if(!gheader.dateMonth)
1266 { 1268 {
1267 header.dateYear--; 1269 gheader.dateYear--;
1268 header.dateMonth = 12; 1270 gheader.dateMonth = 12;
1269 header.dateDay = 31; 1271 gheader.dateDay = 31;
1270 } 1272 }
1271 else 1273 else
1272 { 1274 {
1273 if(header.dateMonth == 2) 1275 if(gheader.dateMonth == 2)
1274 header.dateDay = 28; 1276 gheader.dateDay = 28;
1275 else 1277 else
1276 if((header.dateMonth == 4) || (header.dateMonth == 6) || (header.dateMonth == 9) || (header.dateMonth == 11)) 1278 if((gheader.dateMonth == 4) || (gheader.dateMonth == 6) || (gheader.dateMonth == 9) || (gheader.dateMonth == 11))
1277 header.dateDay = 30; 1279 gheader.dateDay = 30;
1278 else 1280 else
1279 header.dateDay = 31; 1281 gheader.dateDay = 31;
1280 } 1282 }
1281 } 1283 }
1282 } 1284 }
1283 } 1285 }
1284 1286
1285 /* duration */ 1287 /* duration */
1286 header.total_diveTime_seconds = pStateReal->lifeData.dive_time_seconds; 1288 gheader.total_diveTime_seconds = pStateReal->lifeData.dive_time_seconds;
1287 header.maxDepth = pStateReal->lifeData.max_depth_meter * 100; 1289 gheader.maxDepth = pStateReal->lifeData.max_depth_meter * 100;
1288 1290
1289 /* old: 1291 /* old:
1290 1292
1291 secondsAtShallow = pSettings->timeoutDiveReachedZeroDepth; 1293 secondsAtShallow = pSettings->timeoutDiveReachedZeroDepth;
1292 if(pStateReal->lifeData.dive_time_seconds <= secondsAtShallow) 1294 if(pStateReal->lifeData.dive_time_seconds <= secondsAtShallow)
1293 secondsAtShallow = 0; 1295 secondsAtShallow = 0;
1294 header.diveTimeMinutes = (header.total_diveTime_seconds - secondsAtShallow )/ 60; 1296 header.diveTimeMinutes = (header.total_diveTime_seconds - secondsAtShallow )/ 60;
1295 header.diveTimeSeconds = header.total_diveTime_seconds - secondsAtShallow - (header.diveTimeMinutes * 60); 1297 header.diveTimeSeconds = header.total_diveTime_seconds - secondsAtShallow - (header.diveTimeMinutes * 60);
1296 */ 1298 */
1297 divetimeHelper = pStateReal->lifeData.dive_time_seconds_without_surface_time; 1299 divetimeHelper = pStateReal->lifeData.dive_time_seconds_without_surface_time;
1298 header.diveTimeMinutes = (uint16_t)(divetimeHelper/60); 1300 gheader.diveTimeMinutes = (uint16_t)(divetimeHelper/60);
1299 divetimeHelper -= 60 * (uint32_t)header.diveTimeMinutes; 1301 divetimeHelper -= 60 * (uint32_t)gheader.diveTimeMinutes;
1300 header.diveTimeSeconds = (uint16_t)divetimeHelper; 1302 gheader.diveTimeSeconds = (uint16_t)divetimeHelper;
1301 1303
1302 /* deco algorithm (final) */ 1304 /* deco algorithm (final) */
1303 if(pStateReal->diveSettings.deco_type.ub.standard == GF_MODE) 1305 if(pStateReal->diveSettings.deco_type.ub.standard == GF_MODE)
1304 { 1306 {
1305 header.decoModel = 1; 1307 gheader.decoModel = 1;
1306 header.gfLow_or_Vpm_conservatism = pStateReal->diveSettings.gf_low; 1308 gheader.gfLow_or_Vpm_conservatism = pStateReal->diveSettings.gf_low;
1307 header.gfHigh = pStateReal->diveSettings.gf_high; 1309 gheader.gfHigh = pStateReal->diveSettings.gf_high;
1308 } 1310 }
1309 else 1311 else
1310 { 1312 {
1311 header.decoModel = 2; 1313 gheader.decoModel = 2;
1312 header.gfLow_or_Vpm_conservatism = pStateReal->diveSettings.vpm_conservatism; 1314 gheader.gfLow_or_Vpm_conservatism = pStateReal->diveSettings.vpm_conservatism;
1313 header.gfHigh = 0; 1315 gheader.gfHigh = 0;
1314 } 1316 }
1315 1317
1316 /* tissue load */ 1318 /* tissue load */
1317 memcpy(header.n2Compartments, pStateReal->lifeData.tissue_nitrogen_bar, 64); 1319 memcpy(gheader.n2Compartments, pStateReal->lifeData.tissue_nitrogen_bar, 64);
1318 memcpy(header.heCompartments, pStateReal->lifeData.tissue_helium_bar, 64); 1320 memcpy(gheader.heCompartments, pStateReal->lifeData.tissue_helium_bar, 64);
1319 1321
1320 } 1322 }
1321 1323
1322 1324
1323 static void logbook_SetAverageDepth(float average_depth_meter) 1325 static void logbook_SetAverageDepth(float average_depth_meter)
1324 { 1326 {
1325 header.averageDepth_mbar = (uint16_t)(average_depth_meter * 100); 1327 gheader.averageDepth_mbar = (uint16_t)(average_depth_meter * 100);
1326 } 1328 }
1327 1329
1328 1330
1329 static void logbook_SetMinTemperature(float min_temperature_celsius) 1331 static void logbook_SetMinTemperature(float min_temperature_celsius)
1330 { 1332 {
1331 header.minTemp = (int16_t)((min_temperature_celsius * 10.0f) + 0.5f); 1333 gheader.minTemp = (int16_t)((min_temperature_celsius * 10.0f) + 0.5f);
1332 } 1334 }
1333 1335
1334 1336
1335 static void logbook_SetMaxCNS(float max_cns_percentage) 1337 static void logbook_SetMaxCNS(float max_cns_percentage)
1336 { 1338 {
1337 if(max_cns_percentage < 9999) 1339 if(max_cns_percentage < 9999)
1338 header.maxCNS = (uint16_t)(max_cns_percentage); 1340 gheader.maxCNS = (uint16_t)(max_cns_percentage);
1339 else 1341 else
1340 header.maxCNS = 9999; 1342 gheader.maxCNS = 9999;
1341 } 1343 }
1342 1344
1343 1345
1344 static void logbook_SetCompartmentDesaturation(const SDiveState * pStateReal) 1346 static void logbook_SetCompartmentDesaturation(const SDiveState * pStateReal)
1345 { 1347 {
1347 1349
1348 decom_tissues_desaturation_time(&pStateReal->lifeData, &secondaryInformation); 1350 decom_tissues_desaturation_time(&pStateReal->lifeData, &secondaryInformation);
1349 for(int i=0;i<16;i++) 1351 for(int i=0;i<16;i++)
1350 { 1352 {
1351 if(secondaryInformation.tissue_nitrogen_desaturation_time_minutes[i] <= (15 * 255)) 1353 if(secondaryInformation.tissue_nitrogen_desaturation_time_minutes[i] <= (15 * 255))
1352 header.n2CompartDesatTime_min[i] = (uint8_t)((secondaryInformation.tissue_nitrogen_desaturation_time_minutes[i] + 14) / 15); 1354 gheader.n2CompartDesatTime_min[i] = (uint8_t)((secondaryInformation.tissue_nitrogen_desaturation_time_minutes[i] + 14) / 15);
1353 else 1355 else
1354 header.n2CompartDesatTime_min[i] = 255; 1356 gheader.n2CompartDesatTime_min[i] = 255;
1355 if(secondaryInformation.tissue_helium_desaturation_time_minutes[i] <= (15 * 255)) 1357 if(secondaryInformation.tissue_helium_desaturation_time_minutes[i] <= (15 * 255))
1356 header.heCompartDesatTime_min[i] = (uint8_t)((secondaryInformation.tissue_helium_desaturation_time_minutes[i] + 14 )/ 15); 1358 gheader.heCompartDesatTime_min[i] = (uint8_t)((secondaryInformation.tissue_helium_desaturation_time_minutes[i] + 14 )/ 15);
1357 else 1359 else
1358 header.heCompartDesatTime_min[i] = 255; 1360 gheader.heCompartDesatTime_min[i] = 255;
1359 } 1361 }
1360 } 1362 }
1361 1363
1362 static void logbook_SetLastStop(float last_stop_depth_bar) 1364 static void logbook_SetLastStop(float last_stop_depth_bar)
1363 { 1365 {
1364 header.lastDecostop_m = (uint8_t)(last_stop_depth_bar / 10.0f); 1366 gheader.lastDecostop_m = (uint8_t)(last_stop_depth_bar / 10.0f);
1365 } 1367 }
1366 1368
1367 static void logbook_writedata(void * data, int length_byte) 1369 static void logbook_writedata(void * data, int length_byte)
1368 { 1370 {
1369 ext_flash_write_sample(data, length_byte); 1371 ext_flash_write_sample(data, length_byte);
1370 } 1372 }
1371
1372 1373
1373 /******************************************************************************** 1374 /********************************************************************************
1374 * @brief logbook_build_ostc3header. / 1375 * @brief logbook_build_ostc3header. /
1375 * @author heinrichs weikamp gmbh 1376 * @author heinrichs weikamp gmbh
1376 * @version V0.0.2 1377 * @version V0.0.2
1377 * @date 27-Nov-2014 1378 * @date 27-Nov-2014
1378 *********************************************************************************/ 1379 *********************************************************************************/
1379 SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead) 1380 SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead)
1380 { 1381 {
1381 convert_Type data; 1382 convert_Type data,data2;
1382 1383
1383 memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2); 1384 memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2);
1384 memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3); 1385 memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3);
1385 memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3); 1386 memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3);
1386 1387
1388
1387 data.u8bit.byteHigh = 0; 1389 data.u8bit.byteHigh = 0;
1388 data.u8bit.byteLow = pHead->profileLength[0]; 1390 data.u8bit.byteLow = pHead->pBeginProfileData[0];
1389 data.u8bit.byteMidLow = pHead->profileLength[1]; 1391 data.u8bit.byteMidLow = pHead->pBeginProfileData[1];
1390 data.u8bit.byteMidHigh = pHead->profileLength[2]; 1392 data.u8bit.byteMidHigh = pHead->pBeginProfileData[2];
1391 1393
1394 data2.u8bit.byteHigh = 0;
1395 data2.u8bit.byteLow = pHead->pEndProfileData[0];
1396 data2.u8bit.byteMidLow = pHead->pEndProfileData[1];
1397 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2];
1398
1399 /* check if sample address information are corrupted by address range. */
1400 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
1401 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
1402 {
1403 data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
1404 pHead->pEndProfileData[0] = data2.u8bit.byteLow;
1405 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
1406 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
1407 data.u32bit = DEFAULT_SAMPLES;
1408 }
1409 else
1410 {
1411 data.u8bit.byteHigh = 0;
1412 data.u8bit.byteLow = pHead->profileLength[0];
1413 data.u8bit.byteMidLow = pHead->profileLength[1];
1414 data.u8bit.byteMidHigh = pHead->profileLength[2];
1415 }
1392 if(data.u32bit != 0xFFFFFF) 1416 if(data.u32bit != 0xFFFFFF)
1393 data.u32bit += 3; 1417 data.u32bit += 3;
1394 1418
1395 headerOSTC3.profileLength[0] = data.u8bit.byteLow; 1419 headerOSTC3.profileLength[0] = data.u8bit.byteLow;
1396 headerOSTC3.profileLength[1] = data.u8bit.byteMidLow; 1420 headerOSTC3.profileLength[1] = data.u8bit.byteMidLow;
1500 * @version V0.0.1 1524 * @version V0.0.1
1501 * @date 31-Juli-2015 1525 * @date 31-Juli-2015
1502 *********************************************************************************/ 1526 *********************************************************************************/
1503 SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead) 1527 SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead)
1504 { 1528 {
1505 convert_Type data; 1529 convert_Type data, data2;
1530
1506 1531
1507 data.u8bit.byteHigh = 0; 1532 data.u8bit.byteHigh = 0;
1508 data.u8bit.byteLow = pHead->profileLength[0]; 1533 data.u8bit.byteLow = pHead->pBeginProfileData[0];
1509 data.u8bit.byteMidLow = pHead->profileLength[1]; 1534 data.u8bit.byteMidLow = pHead->pBeginProfileData[1];
1510 data.u8bit.byteMidHigh = pHead->profileLength[2]; 1535 data.u8bit.byteMidHigh = pHead->pBeginProfileData[2];
1536
1537 data2.u8bit.byteHigh = 0;
1538 data2.u8bit.byteLow = pHead->pEndProfileData[0];
1539 data2.u8bit.byteMidLow = pHead->pEndProfileData[1];
1540 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2];
1541
1542 /* check if sample address information are corrupted by address range. */
1543 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
1544 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
1545 {
1546 data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
1547 pHead->pEndProfileData[0] = data2.u8bit.byteLow;
1548 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
1549 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
1550 data.u32bit = DEFAULT_SAMPLES;
1551 }
1552 else
1553 {
1554 data.u8bit.byteHigh = 0;
1555 data.u8bit.byteLow = pHead->profileLength[0];
1556 data.u8bit.byteMidLow = pHead->profileLength[1];
1557 data.u8bit.byteMidHigh = pHead->profileLength[2];
1558 }
1511 1559
1512 if(data.u32bit != 0xFFFFFF) 1560 if(data.u32bit != 0xFFFFFF)
1513 { 1561 {
1514 data.u32bit += 3; 1562 data.u32bit += 3;
1515 1563