comparison Discovery/Src/logbook.c @ 455:928a14568689 minor_improvments

Reactivated samples for bottle pressure information: I previous versions (and also in the upcommings) the bottle pressure informations are not added to the log information. However for alfatesting of a potential pressure measurement the function may now be reactivated by a compile switch Added the possibility to create dummy profiles based on the max depth, time and temperature values stored in the dive header: In case the sample information belonging to a dive is no longer available a dummy profile shall be provided to the consumers (infolog view as well as external read requests).
author ideenmodellierer
date Tue, 24 Mar 2020 22:12:08 +0100
parents ee1434824c3f
children 4bd01f48c285
comparison
equal deleted inserted replaced
454:5a633dece17a 455:928a14568689
55 #include "externLogbookFlash.h" 55 #include "externLogbookFlash.h"
56 #include "data_exchange.h" 56 #include "data_exchange.h"
57 #include "decom.h" 57 #include "decom.h"
58 #include "tHome.h" // for tHome_findNextStop() 58 #include "tHome.h" // for tHome_findNextStop()
59 #include "settings.h" 59 #include "settings.h"
60 #include "configuration.h"
60 61
61 /* Private types -------------------------------------------------------------*/ 62 /* Private types -------------------------------------------------------------*/
62 63
63 #define LOGBOOK_VERSION (0x30) 64 #define LOGBOOK_VERSION (0x30)
64 #define LOGBOOK_VERSION_OSTC3 (0x24) 65 #define LOGBOOK_VERSION_OSTC3 (0x24)
65 66
66 #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */ 67 #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */
68 #define DUMMY_SAMPLES (1000) /* Maximum number of samples profided by a dummy dive profile */
67 69
68 typedef struct /* don't forget to adjust void clear_divisor(void) */ 70 typedef struct /* don't forget to adjust void clear_divisor(void) */
69 { 71 {
70 uint8_t temperature; 72 uint8_t temperature;
71 uint8_t deco_ndl; 73 uint8_t deco_ndl;
83 static SLogbookHeaderOSTC3 headerOSTC3; 85 static SLogbookHeaderOSTC3 headerOSTC3;
84 static SLogbookHeaderOSTC3compact headerOSTC3compact; 86 static SLogbookHeaderOSTC3compact headerOSTC3compact;
85 static SSmallHeader smallHeader; 87 static SSmallHeader smallHeader;
86 static SDivisor divisor; 88 static SDivisor divisor;
87 static SDivisor divisorBackup; 89 static SDivisor divisorBackup;
90
91 static SSmallHeader smallDummyHeader;
92 static uint16_t dummyWriteIdx;
93 static uint16_t dummyReadIdx;
94 static uint8_t dummyMemoryBuffer[1000*4];
95
88 96
89 /* Private function prototypes -----------------------------------------------*/ 97 /* Private function prototypes -----------------------------------------------*/
90 static void clear_divisor(void); 98 static void clear_divisor(void);
91 static void logbook_SetAverageDepth(float average_depth_meter); 99 static void logbook_SetAverageDepth(float average_depth_meter);
92 static void logbook_SetMinTemperature(float min_temperature_celsius); 100 static void logbook_SetMinTemperature(float min_temperature_celsius);
93 static void logbook_SetMaxCNS(float max_cns_percentage); 101 static void logbook_SetMaxCNS(float max_cns_percentage);
94 static void logbook_SetCompartmentDesaturation(const SDiveState * pStateReal); 102 static void logbook_SetCompartmentDesaturation(const SDiveState * pStateReal);
95 static void logbook_SetLastStop(float last_stop_depth_bar); 103 static void logbook_SetLastStop(float last_stop_depth_bar);
96 static void logbook_writedata(void * data, int length_byte); 104 static void logbook_writedata(void * data, int length_byte);
97 static void logbook_UpdateHeader(const SDiveState * pStateReal); 105 static void logbook_UpdateHeader(const SDiveState * pStateReal);
106 static void logbook_createDummyProfile(uint16_t maxDepth, uint8_t lastDecostop_m, int16_t minTemp, uint16_t length, uint16_t* depth, int16_t* temperature);
98 107
99 /* Exported functions --------------------------------------------------------*/ 108 /* Exported functions --------------------------------------------------------*/
100 109
101 void logbook_EndDive(void) 110 void logbook_EndDive(void)
102 { 111 {
305 smallHeader.cnsType = 5; 314 smallHeader.cnsType = 5;
306 smallHeader.cnsLength = 2; 315 smallHeader.cnsLength = 2;
307 smallHeader.cnsDivisor = 12; 316 smallHeader.cnsDivisor = 12;
308 317
309 smallHeader.tankType = 6; 318 smallHeader.tankType = 6;
319 #ifdef ENABLE_BOTTLE_SENSOR
320 smallHeader.tankLength = 2;
321 smallHeader.tankDivisor = 30; /* log tank data once a minute */
322 #else
310 smallHeader.tankLength = 0; 323 smallHeader.tankLength = 0;
311 smallHeader.tankDivisor = 0; 324 smallHeader.tankDivisor = 0;
312 325 #endif
313 logbook_writedata((void *) &smallHeader,sizeof(smallHeader)); 326 logbook_writedata((void *) &smallHeader,sizeof(smallHeader));
314 327
315 clear_divisor(); 328 clear_divisor();
316 } 329 }
317 330
621 else 634 else
622 { 635 {
623 divisor.cns--; 636 divisor.cns--;
624 } 637 }
625 638
639 #ifdef ENABLE_BOTTLE_SENSOR
640 if(smallHeader.tankDivisor)
641 {
642 if(divisor.tank == 0)
643 {
644 divisor.tank = smallHeader.tankDivisor - 1;
645 addS16(&sample[length], ((state->lifeData.bottle_bar[state->lifeData.actualGas.GasIdInSettings])));
646 length += smallHeader.tankLength;
647 }
648 else
649 {
650 divisor.tank--;
651 }
652 }
653 #endif
654
626 profileByteFlag.uw = length - 3; 655 profileByteFlag.uw = length - 3;
627 if(eventByte1.uw) 656 if(eventByte1.uw)
628 { 657 {
629 profileByteFlag.ub.bit7 = 1; 658 profileByteFlag.ub.bit7 = 1;
630 } 659 }
646 * @param int32_t* temperature: output Value 675 * @param int32_t* temperature: output Value
647 * @param int32_t* sensor1, sensor2, sensor3: output Value 676 * @param int32_t* sensor1, sensor2, sensor3: output Value
648 * @param int32_t* cns: output Value 677 * @param int32_t* cns: output Value
649 * @return bytes read / 0 = reading Error 678 * @return bytes read / 0 = reading Error
650 */ 679 */
651 static uint16_t readSample(int32_t* depth, int16_t * gasid, int16_t* setpoint_cbar, int32_t* temperature, int32_t* sensor1, int32_t* sensor2, int32_t* sensor3, int32_t* cns, SManualGas* manualGas, int16_t* bailout, int16_t* decostopDepth) 680 static uint16_t readSample(int32_t* depth, int16_t * gasid, int16_t* setpoint_cbar, int32_t* temperature, int32_t* sensor1, int32_t* sensor2,
681 int32_t* sensor3, int32_t* cns, SManualGas* manualGas, int16_t* bailout, int16_t* decostopDepth, uint16_t* tank)
652 { 682 {
653 int length = 0; 683 int length = 0;
654 _Bool bEvent = 0; 684 _Bool bEvent = 0;
655 bit8_Type eventByte1, eventByte2; 685 bit8_Type eventByte1, eventByte2;
656 bit8_Type profileByteFlag; 686 bit8_Type profileByteFlag;
675 *cns = -1; 705 *cns = -1;
676 if(setpoint_cbar) 706 if(setpoint_cbar)
677 *setpoint_cbar = -1; 707 *setpoint_cbar = -1;
678 if(bailout) 708 if(bailout)
679 *bailout = -1; 709 *bailout = -1;
710 if(tank)
711 *tank = 0;
712
680 if(manualGas) 713 if(manualGas)
681 { 714 {
682 manualGas->percentageO2 =-1; 715 manualGas->percentageO2 =-1;
683 manualGas->percentageHe =-1; 716 manualGas->percentageHe =-1;
684 } 717 }
865 else 898 else
866 { 899 {
867 divisor.cns--; 900 divisor.cns--;
868 } 901 }
869 902
903 #ifdef ENABLE_BOTTLE_SENSOR
904 if(smallHeader.tankDivisor)
905 {
906 if(divisor.tank == 0)
907 {
908 divisor.tank = smallHeader.tankDivisor - 1;
909 ext_flash_read_next_sample_part( (uint8_t*)&temp, 2);
910 bytesRead +=2;
911 length -= 2;
912 if(tank)
913 {
914 *tank = (uint16_t)temp;
915 }
916 }
917 else
918 {
919 divisor.tank--;
920 }
921 }
922 #endif
923
870 if (length != 0) 924 if (length != 0)
871 return 0; 925 return 0;
872 926
873 return bytesRead; 927 return bytesRead;
874 } 928 }
887 * @param int32_t* temperature : output array 941 * @param int32_t* temperature : output array
888 * @param int32_t* ppo2 : output array 942 * @param int32_t* ppo2 : output array
889 * @param int32_t* cns : output array 943 * @param int32_t* cns : output array
890 * @return length of output 944 * @return length of output
891 */ 945 */
892 uint16_t logbook_readSampleData(uint8_t StepBackwards, uint16_t length,uint16_t* depth, uint8_t* gasid, int16_t* temperature, uint16_t* ppo2, uint16_t* setpoint, uint16_t* sensor1, uint16_t* sensor2, uint16_t* sensor3, uint16_t* cns, uint8_t* bailout, uint16_t* decostopDepth) 946 uint16_t logbook_readSampleData(uint8_t StepBackwards, uint16_t length,uint16_t* depth, uint8_t* gasid, int16_t* temperature, uint16_t* ppo2,
947 uint16_t* setpoint, uint16_t* sensor1, uint16_t* sensor2, uint16_t* sensor3, uint16_t* cns, uint8_t* bailout,
948 uint16_t* decostopDepth, uint16_t* tank)
893 { 949 {
894 //Test read 950 //Test read
895 //SLogbookHeader header; 951 //SLogbookHeader header;
896 952
897 //logbook_getHeader(&header); 953 //logbook_getHeader(&header);
919 int32_t depthLast = 0; 975 int32_t depthLast = 0;
920 int16_t gasidLast = 0; 976 int16_t gasidLast = 0;
921 int32_t temperatureLast = 0; 977 int32_t temperatureLast = 0;
922 int32_t temperatureFirst = 0; 978 int32_t temperatureFirst = 0;
923 int32_t cnsLast = 0; 979 int32_t cnsLast = 0;
924 int16_t decostepDepthVal = 0; 980 int16_t decostepDepthVal = 0;
925 int16_t decostepDepthLast = 0; 981 int16_t decostepDepthLast = 0;
982 int16_t tankVal = 0;
926 983
927 SManualGas manualGasVal; 984 SManualGas manualGasVal;
928 SManualGas manualGasLast; 985 SManualGas manualGasLast;
929 manualGasLast.percentageO2 = 0; 986 manualGasLast.percentageO2 = 0;
930 manualGasLast.percentageHe = 0; 987 manualGasLast.percentageHe = 0;
988 uint16_t numSamples = 0;
931 989
932 float ambiant_pressure_bar = 0; 990 float ambiant_pressure_bar = 0;
933 float ppO2 = 0; 991 float ppO2 = 0;
934 ext_flash_read_dive_header((uint8_t*)&header, StepBackwards); 992 ext_flash_read_dive_header((uint8_t*)&header, StepBackwards);
935 for(i = 0;i< 5;i++) 993 for(i = 0;i< 5;i++)
943 else 1001 else
944 setPointLast = 0; 1002 setPointLast = 0;
945 //diveTime_seconds = header.diveTime_seconds ; 1003 //diveTime_seconds = header.diveTime_seconds ;
946 for(compression = 1; compression < 100; compression ++) 1004 for(compression = 1; compression < 100; compression ++)
947 { 1005 {
948 if((header.total_diveTime_seconds / header.samplingRate)/compression <= length) 1006 numSamples = (header.total_diveTime_seconds / header.samplingRate)/compression;
949 break; 1007 if(numSamples <= length)
1008 {
1009 break;
1010 }
950 } 1011 }
951 1012
952 1013
953 for(i = 0;i< length;i++) 1014 for(i = 0;i< length;i++)
954 { 1015 {
968 sensor2[i] = 0; 1029 sensor2[i] = 0;
969 if(sensor3) 1030 if(sensor3)
970 sensor3[i] = 0; 1031 sensor3[i] = 0;
971 if(cns) 1032 if(cns)
972 cns[i] = 0; 1033 cns[i] = 0;
1034 if(tank)
1035 tank[i] = 0;
973 } 1036 }
974 //We start with fist gasid 1037 //We start with fist gasid
975 gasidLast = firstgasid; 1038 gasidLast = firstgasid;
976 1039
977 1040
985 clear_divisor(); 1048 clear_divisor();
986 1049
987 iNum = 0; 1050 iNum = 0;
988 int counter = 0; 1051 int counter = 0;
989 temperatureLast = -1000; 1052 temperatureLast = -1000;
990 while ((bytesRead < totalNumberOfBytes) && (iNum < length)) 1053 if(totalNumberOfBytes > 2) /* read real data */
991 { 1054 {
992 ext_flash_set_entry_point(); 1055 while ((bytesRead < totalNumberOfBytes) && (iNum < length))
993 divisorBackup = divisor; 1056 {
994 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, &decostepDepthVal); 1057 ext_flash_set_entry_point();
995 1058 divisorBackup = divisor;
996 if(retVal == 0) 1059 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal,
997 { 1060 &bailoutVal, &decostepDepthVal, &tankVal);
998 //Error try to read again!!! 1061
999 ext_flash_reopen_read_sample_at_entry_point(); 1062 if(retVal == 0)
1000 divisor = divisorBackup;
1001 retVal = readSample(&depthVal,&gasidVal,&setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, &decostepDepthVal);
1002
1003 if(retVal == 0)
1004 break;
1005 }
1006 bytesRead +=retVal;
1007
1008 //if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value
1009 if(depthVal == -1)
1010 depthVal = depthLast;
1011 else
1012 depthLast = depthVal;
1013
1014 if(gasidVal == -1)
1015 gasidVal = gasidLast;
1016 else
1017 gasidLast = gasidVal;
1018
1019 if(temperatureVal == -1000)
1020 temperatureVal = temperatureLast;
1021 else
1022 {
1023 if(temperatureLast == -1000)
1024 temperatureFirst = temperatureVal;
1025 temperatureLast = temperatureVal;
1026 }
1027
1028 if(setPointVal == -1)
1029 setPointVal = setPointLast;
1030 else
1031 setPointLast = setPointVal;
1032
1033 if(sensor1Val == -1)
1034 sensor1Val = sensor1Last;
1035 else
1036 sensor1Last = sensor1Val;
1037
1038 if(sensor2Val == -1)
1039 sensor2Val = sensor2Last;
1040 else
1041 sensor2Last = sensor2Val;
1042
1043 if(sensor3Val == -1)
1044 sensor3Val = sensor3Last;
1045 else
1046 sensor3Last = sensor3Val;
1047
1048 if(cnsVal == -1)
1049 cnsVal = cnsLast;
1050 else
1051 cnsLast = cnsVal;
1052
1053 if(manualGasVal.percentageO2 == -1)
1054 manualGasVal = manualGasLast;
1055 else
1056 manualGasLast = manualGasVal;
1057
1058 if(bailoutVal == -1)
1059 bailoutVal = bailoutLast;
1060 else
1061 bailoutLast = bailoutVal;
1062
1063 if(decostepDepthVal == -1)
1064 decostepDepthVal = decostepDepthLast;
1065 else
1066 decostepDepthLast = decostepDepthVal;
1067
1068 counter++;
1069 // Heed compression
1070 // Write here to arrays
1071 if(counter == compression)
1072 {
1073 if(depth)
1074 depth[iNum] = depthVal;
1075 if(gasid)
1076 gasid[iNum] = gasidVal;
1077 if(temperature)
1078 temperature[iNum] = temperatureVal;
1079 if(cns)
1080 cns[iNum] = cnsVal;
1081 if(bailout)
1082 bailout[iNum] = bailoutVal;
1083 if(decostopDepth)
1084 decostopDepth[iNum] = decostepDepthVal;
1085
1086 if(ppo2)
1087 { 1063 {
1088 //Calc ppo2 - Values 1064 //Error try to read again!!!
1089 SGas gas; 1065 ext_flash_reopen_read_sample_at_entry_point();
1090 gas.setPoint_cbar = setPointVal; 1066 divisor = divisorBackup;
1091 if(gasidVal > 0) 1067 retVal = readSample(&depthVal,&gasidVal,&setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal,
1068 &manualGasVal, &bailoutVal, &decostepDepthVal, &tankVal);
1069
1070 if(retVal == 0)
1071 break;
1072 }
1073 bytesRead +=retVal;
1074
1075 //if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value
1076 if(depthVal == -1)
1077 depthVal = depthLast;
1078 else
1079 depthLast = depthVal;
1080
1081 if(gasidVal == -1)
1082 gasidVal = gasidLast;
1083 else
1084 gasidLast = gasidVal;
1085
1086 if(temperatureVal == -1000)
1087 temperatureVal = temperatureLast;
1088 else
1089 {
1090 if(temperatureLast == -1000)
1091 temperatureFirst = temperatureVal;
1092 temperatureLast = temperatureVal;
1093 }
1094
1095 if(setPointVal == -1)
1096 setPointVal = setPointLast;
1097 else
1098 setPointLast = setPointVal;
1099
1100 if(sensor1Val == -1)
1101 sensor1Val = sensor1Last;
1102 else
1103 sensor1Last = sensor1Val;
1104
1105 if(sensor2Val == -1)
1106 sensor2Val = sensor2Last;
1107 else
1108 sensor2Last = sensor2Val;
1109
1110 if(sensor3Val == -1)
1111 sensor3Val = sensor3Last;
1112 else
1113 sensor3Last = sensor3Val;
1114
1115 if(cnsVal == -1)
1116 cnsVal = cnsLast;
1117 else
1118 cnsLast = cnsVal;
1119
1120 if(manualGasVal.percentageO2 == -1)
1121 manualGasVal = manualGasLast;
1122 else
1123 manualGasLast = manualGasVal;
1124
1125 if(bailoutVal == -1)
1126 bailoutVal = bailoutLast;
1127 else
1128 bailoutLast = bailoutVal;
1129
1130 if(decostepDepthVal == -1)
1131 decostepDepthVal = decostepDepthLast;
1132 else
1133 decostepDepthLast = decostepDepthVal;
1134
1135 counter++;
1136 // Heed compression
1137 // Write here to arrays
1138 if(counter == compression)
1139 {
1140 if(depth)
1141 depth[iNum] = depthVal;
1142 if(gasid)
1143 gasid[iNum] = gasidVal;
1144 if(temperature)
1145 temperature[iNum] = temperatureVal;
1146 if(cns)
1147 cns[iNum] = cnsVal;
1148 if(bailout)
1149 bailout[iNum] = bailoutVal;
1150 if(decostopDepth)
1151 decostopDepth[iNum] = decostepDepthVal;
1152
1153 if(ppo2)
1092 { 1154 {
1093 gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage; 1155 //Calc ppo2 - Values
1094 gas.nitrogen_percentage = 100 - gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage; 1156 SGas gas;
1157 gas.setPoint_cbar = setPointVal;
1158 if(gasidVal > 0)
1159 {
1160 gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage;
1161 gas.nitrogen_percentage = 100 - gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage;
1162 }
1163 else
1164 {
1165 gas.helium_percentage = manualGasVal.percentageHe;
1166 gas.nitrogen_percentage = 100 - gas.helium_percentage - manualGasVal.percentageO2;
1167 }
1168 ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000;
1169 ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas );
1170 ppo2[iNum] = (uint16_t) ( ppO2 * 100);
1095 } 1171 }
1096 else 1172
1173 if(tank)
1097 { 1174 {
1098 gas.helium_percentage = manualGasVal.percentageHe; 1175 tank[iNum] = tankVal;
1099 gas.nitrogen_percentage = 100 - gas.helium_percentage - manualGasVal.percentageO2;
1100 } 1176 }
1101 ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000; 1177 if(setpoint)
1102 ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas ); 1178 setpoint[iNum] = setPointVal;
1103 ppo2[iNum] = (uint16_t) ( ppO2 * 100); 1179
1180 if(sensor1)
1181 sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF;
1182 if(sensor2)
1183 sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF;
1184 if(sensor3)
1185 sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF;
1186 iNum++;
1187 counter = 0;
1104 } 1188 }
1105 1189 }
1106 if(setpoint) 1190 }
1107 setpoint[iNum] = setPointVal; 1191 else
1108 1192 {
1109 if(sensor1) 1193 logbook_createDummyProfile(header.maxDepth, header.lastDecostop_m, header.minTemp, numSamples, depth, temperature);
1110 sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF; 1194 iNum = numSamples;
1111 if(sensor2) 1195 }
1112 sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF;
1113 if(sensor3)
1114 sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF;
1115 iNum++;
1116 counter = 0;
1117 }
1118 }
1119 1196
1120 // Fix first Temperature Entries 150930 hw 1197 // Fix first Temperature Entries 150930 hw
1121 if(temperature) 1198 if(temperature)
1122 { 1199 {
1123 int i = 0; 1200 int i = 0;
1379 * @date 27-Nov-2014 1456 * @date 27-Nov-2014
1380 *********************************************************************************/ 1457 *********************************************************************************/
1381 SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead) 1458 SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead)
1382 { 1459 {
1383 convert_Type data,data2; 1460 convert_Type data,data2;
1461 uint16_t dummyLength = 0;
1384 1462
1385 memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2); 1463 memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2);
1386 memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3); 1464 memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3);
1387 memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3); 1465 memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3);
1388 1466
1395 data2.u8bit.byteHigh = 0; 1473 data2.u8bit.byteHigh = 0;
1396 data2.u8bit.byteLow = pHead->pEndProfileData[0]; 1474 data2.u8bit.byteLow = pHead->pEndProfileData[0];
1397 data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; 1475 data2.u8bit.byteMidLow = pHead->pEndProfileData[1];
1398 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; 1476 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2];
1399 1477
1400 /* check if sample address information are corrupted by address range. */ 1478 if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */
1401 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ 1479 &&(pHead->pBeginProfileData[1] == 0)
1402 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) 1480 &&(pHead->pBeginProfileData[2] == 0))
1403 { 1481 {
1404 data2.u32bit = data.u32bit + DEFAULT_SAMPLES; 1482 dummyLength = logbook_fillDummySampleBuffer(pHead->diveTimeMinutes, pHead->diveTimeSeconds,pHead->maxDepth
1405 pHead->pEndProfileData[0] = data2.u8bit.byteLow; 1483 ,pHead->lastDecostop_m, pHead->minTemp);
1406 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; 1484
1407 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; 1485 data2.u32bit = data.u32bit + dummyLength; /* calc new end address (which is equal to dummyLength) */
1408 data.u32bit = DEFAULT_SAMPLES; 1486 data.u32bit = data2.u32bit; /* data is used below to represent the length */
1409 } 1487 }
1410 else 1488 else
1411 { 1489 {
1412 data.u8bit.byteHigh = 0; 1490 /* check if sample address information are corrupted by address range. */
1413 data.u8bit.byteLow = pHead->profileLength[0]; 1491 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
1414 data.u8bit.byteMidLow = pHead->profileLength[1]; 1492 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
1415 data.u8bit.byteMidHigh = pHead->profileLength[2]; 1493 {
1494 data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
1495 pHead->pEndProfileData[0] = data2.u8bit.byteLow;
1496 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
1497 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
1498 data.u32bit = DEFAULT_SAMPLES;
1499 }
1500 else
1501 {
1502 data.u8bit.byteHigh = 0;
1503 data.u8bit.byteLow = pHead->profileLength[0];
1504 data.u8bit.byteMidLow = pHead->profileLength[1];
1505 data.u8bit.byteMidHigh = pHead->profileLength[2];
1506 }
1416 } 1507 }
1417 if(data.u32bit != 0xFFFFFF) 1508 if(data.u32bit != 0xFFFFFF)
1418 data.u32bit += 3; 1509 data.u32bit += 3;
1419 1510
1420 headerOSTC3.profileLength[0] = data.u8bit.byteLow; 1511 headerOSTC3.profileLength[0] = data.u8bit.byteLow;
1526 * @date 31-Juli-2015 1617 * @date 31-Juli-2015
1527 *********************************************************************************/ 1618 *********************************************************************************/
1528 SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead) 1619 SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead)
1529 { 1620 {
1530 convert_Type data, data2; 1621 convert_Type data, data2;
1622 uint32_t dummyLength = 0;
1531 1623
1532 1624
1533 data.u8bit.byteHigh = 0; 1625 data.u8bit.byteHigh = 0;
1534 data.u8bit.byteLow = pHead->pBeginProfileData[0]; 1626 data.u8bit.byteLow = pHead->pBeginProfileData[0];
1535 data.u8bit.byteMidLow = pHead->pBeginProfileData[1]; 1627 data.u8bit.byteMidLow = pHead->pBeginProfileData[1];
1538 data2.u8bit.byteHigh = 0; 1630 data2.u8bit.byteHigh = 0;
1539 data2.u8bit.byteLow = pHead->pEndProfileData[0]; 1631 data2.u8bit.byteLow = pHead->pEndProfileData[0];
1540 data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; 1632 data2.u8bit.byteMidLow = pHead->pEndProfileData[1];
1541 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; 1633 data2.u8bit.byteMidHigh = pHead->pEndProfileData[2];
1542 1634
1543 /* check if sample address information are corrupted by address range. */ 1635 if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */
1544 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ 1636 &&(pHead->pBeginProfileData[1] == 0)
1545 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) 1637 &&(pHead->pBeginProfileData[2] == 0))
1546 { 1638 {
1547 data2.u32bit = data.u32bit + DEFAULT_SAMPLES; 1639 dummyLength = logbook_fillDummySampleBuffer(pHead->diveTimeMinutes, pHead->diveTimeSeconds,pHead->maxDepth
1548 pHead->pEndProfileData[0] = data2.u8bit.byteLow; 1640 ,pHead->lastDecostop_m, pHead->minTemp);
1549 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; 1641
1550 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; 1642 data2.u32bit = data.u32bit + dummyLength; /* calc new end address (which is equal to dummyLength) */
1551 data.u32bit = DEFAULT_SAMPLES; 1643 data.u32bit = data2.u32bit; /* data is used below to represent the length */
1552 } 1644 }
1553 else 1645 else
1554 { 1646 {
1555 data.u8bit.byteHigh = 0; 1647 /* check if sample address information are corrupted by address range. */
1556 data.u8bit.byteLow = pHead->profileLength[0]; 1648 /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */
1557 data.u8bit.byteMidLow = pHead->profileLength[1]; 1649 if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000)))
1558 data.u8bit.byteMidHigh = pHead->profileLength[2]; 1650 {
1559 } 1651 data2.u32bit = data.u32bit + DEFAULT_SAMPLES;
1560 1652 pHead->pEndProfileData[0] = data2.u8bit.byteLow;
1653 pHead->pEndProfileData[1] = data2.u8bit.byteMidLow;
1654 pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh;
1655 data.u32bit = DEFAULT_SAMPLES;
1656 }
1657 else
1658 {
1659 data.u8bit.byteHigh = 0;
1660 data.u8bit.byteLow = pHead->profileLength[0];
1661 data.u8bit.byteMidLow = pHead->profileLength[1];
1662 data.u8bit.byteMidHigh = pHead->profileLength[2];
1663 }
1664 }
1561 if(data.u32bit != 0xFFFFFF) 1665 if(data.u32bit != 0xFFFFFF)
1562 { 1666 {
1563 data.u32bit += 3; 1667 data.u32bit += 3;
1564 1668
1565 headerOSTC3compact.profileLength[0] = data.u8bit.byteLow; 1669 headerOSTC3compact.profileLength[0] = data.u8bit.byteLow;
1637 while (true) 1741 while (true)
1638 { 1742 {
1639 1743
1640 ext_flash_set_entry_point(); 1744 ext_flash_set_entry_point();
1641 divisorBackup = divisor; 1745 divisorBackup = divisor;
1642 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); 1746 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
1643 if(retVal == 0) 1747 if(retVal == 0)
1644 { 1748 {
1645 //Error try to read again!!! 1749 //Error try to read again!!!
1646 ext_flash_reopen_read_sample_at_entry_point(); 1750 ext_flash_reopen_read_sample_at_entry_point();
1647 divisor = divisorBackup; 1751 divisor = divisorBackup;
1648 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); 1752 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
1649 1753
1650 if(retVal == 0) 1754 if(retVal == 0)
1651 { 1755 {
1652 //Error try to read again!!! 1756 //Error try to read again!!!
1653 ext_flash_reopen_read_sample_at_entry_point(); 1757 ext_flash_reopen_read_sample_at_entry_point();
1654 divisor = divisorBackup; 1758 divisor = divisorBackup;
1655 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); 1759 retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL);
1656 1760
1657 if(retVal == 0) 1761 if(retVal == 0)
1658 { 1762 {
1659 ext_flash_reopen_read_sample_at_entry_point(); 1763 ext_flash_reopen_read_sample_at_entry_point();
1660 break; 1764 break;
1681 SSettings * settings = settingsGetPointer(); 1785 SSettings * settings = settingsGetPointer();
1682 settings->lastDiveLogId = headerId; 1786 settings->lastDiveLogId = headerId;
1683 ext_flash_close_new_dive_log((uint8_t *)&header); 1787 ext_flash_close_new_dive_log((uint8_t *)&header);
1684 } 1788 }
1685 1789
1790 void logbook_createDummyProfile(uint16_t maxDepth, uint8_t lastDecostop_m, int16_t minTemp, uint16_t length, uint16_t* depth, int16_t* temperature)
1791 {
1792 uint8_t drawDeco = 1;
1793 uint16_t index = 0;
1794 uint16_t indexDescenStop = 0;
1795 uint16_t indexAscendStart = 0;
1796 uint16_t simDecentDepth = 0;
1797 uint16_t simDecentStep = 0;
1798 uint16_t simAcentDepth = 0;
1799 uint16_t simAcentStep = 0;
1800
1801 simDecentStep = maxDepth / (length / 6); /* first 1/6 for descend */
1802 simAcentStep = maxDepth / (length / 3); /* first 1/3 for ascend */
1803
1804 while((index < length) && (simDecentDepth < maxDepth)) /* draw decent */
1805 {
1806 depth[index] = simDecentDepth;
1807 temperature[index] = minTemp;
1808 index++;
1809 simDecentDepth += simDecentStep;
1810 }
1811 indexDescenStop = index;
1812 index = length -1;
1813 while((index > indexDescenStop) && (simAcentDepth < maxDepth)) /* draw ascend including max deco stop */
1814 {
1815 depth[index] = simAcentDepth;
1816 temperature[index] = minTemp;
1817 if((drawDeco) && (simAcentDepth < lastDecostop_m)) /* draw deco step */
1818 {
1819 drawDeco = length / 10;
1820 while (drawDeco)
1821 {
1822 index--;
1823 depth[index] = simAcentDepth;
1824 temperature[index] = minTemp;
1825 }
1826 }
1827 index--;
1828 simAcentDepth += simAcentStep;
1829 }
1830 indexAscendStart = index;
1831 index = indexDescenStop;
1832 while(index <= indexAscendStart) /* draw isobar dive phase */
1833 {
1834 depth[index] = maxDepth;
1835 temperature[index] = minTemp;
1836 index++;
1837 }
1838 }
1839
1840 void logbook_resetDummy()
1841 {
1842 dummyWriteIdx = 0;
1843 dummyReadIdx = 0;
1844 }
1845
1846 void logbook_writeDummy(void* data, uint16_t length)
1847 {
1848 memcpy(&dummyMemoryBuffer[dummyWriteIdx],(uint8_t *)data, length);
1849 dummyWriteIdx += length;
1850 }
1851 void logbook_writeDummySample(uint16_t depth, int16_t temperature)
1852 {
1853 uint8_t sample[10];
1854 int length = 0;
1855
1856 int i = 0;
1857 for(i = 0; i <10 ;i++) sample[i] = 0;
1858 addU16(sample, depth);
1859 length += 2;
1860 sample[2] = 0;
1861 length++;
1862
1863 if(divisor.temperature == 0)
1864 {
1865 divisor.temperature = smallHeader.tempDivisor - 1;
1866 addS16(&sample[length], temperature);
1867 length += 2;
1868 }
1869 else
1870 {
1871 divisor.temperature--;
1872 }
1873
1874 logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader));
1875 }
1876
1877
1878 uint16_t logbook_fillDummySampleBuffer(uint16_t diveMinutes, uint8_t diveSeconds, uint16_t maxDepth, uint8_t lastDecostop_m, int16_t minTemp)
1879 {
1880 uint16_t depthArray[DUMMY_SAMPLES];
1881 int16_t temperatureArray[DUMMY_SAMPLES];
1882
1883 uint16_t index = 0;
1884 uint16_t dummyBufferSize = 0;
1885 uint16_t dummyProfileLength = 0;
1886 uint32_t overallSecond = diveMinutes * 60 + diveSeconds;
1887
1888 logbook_resetDummy();
1889 clear_divisor();
1890
1891 smallDummyHeader.profileLength[0] = 0xFF;
1892 smallDummyHeader.profileLength[1] = 0xFF;
1893 smallDummyHeader.profileLength[2] = 0xFF;
1894 smallDummyHeader.samplingRate_seconds = 2;
1895 smallDummyHeader.numDivisors = 7;
1896
1897 smallDummyHeader.tempType = 0;
1898 smallDummyHeader.tempLength = 2;
1899 smallDummyHeader.tempDivisor = 6;
1900
1901 smallDummyHeader.deco_ndlType = 1;
1902 smallDummyHeader.deco_ndlLength = 2;
1903 smallDummyHeader.deco_ndlDivisor = 0;
1904
1905 /* GF in % at actual position */
1906 smallDummyHeader.gfType = 2;
1907 smallDummyHeader.gfLength = 1;
1908 smallDummyHeader.gfDivisor = 0;
1909
1910 /* 3 Sensors: 8bit ppO2 in 0.01bar, 16bit voltage in 0,1mV */
1911 smallDummyHeader.ppo2Type = 3;
1912 smallDummyHeader.ppo2Length = 9;
1913 smallDummyHeader.ppo2Divisor = 0;
1914
1915 /* last 15 stops in minutes (last, second_to_last, ... */
1916 /* last stop depth is defined in header */
1917 smallDummyHeader.decoplanType = 4;
1918 smallDummyHeader.decoplanLength = 15;
1919 smallDummyHeader.decoplanDivisor = 0;
1920
1921 smallDummyHeader.cnsType = 5;
1922 smallDummyHeader.cnsLength = 2;
1923 smallDummyHeader.cnsDivisor = 0;
1924
1925 smallDummyHeader.tankType = 6;
1926 smallDummyHeader.tankLength = 2;
1927 smallDummyHeader.tankDivisor = 0;
1928
1929 if((overallSecond / smallDummyHeader.samplingRate_seconds) > DUMMY_SAMPLES) /* reduce sample interval to keep buffer size */
1930 {
1931 smallDummyHeader.samplingRate_seconds = overallSecond / DUMMY_SAMPLES;
1932 dummyProfileLength = DUMMY_SAMPLES;
1933 }
1934 else
1935 {
1936 dummyProfileLength = overallSecond / smallDummyHeader.samplingRate_seconds;
1937 }
1938 logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader));
1939 logbook_createDummyProfile(maxDepth, lastDecostop_m, minTemp, dummyProfileLength, depthArray, temperatureArray);
1940
1941 for (index = 0; index < dummyProfileLength; index++)
1942 {
1943 logbook_writeDummySample(depthArray[index], temperatureArray[index]);
1944 }
1945
1946 dummyBufferSize = dummyWriteIdx;
1947
1948 return dummyBufferSize; /* return size of dummy buffer */
1949 }
1950
1951 void logbook_readDummySamples(uint8_t* pTarget, uint16_t length)
1952 {
1953 memcpy(pTarget,&dummyMemoryBuffer[dummyReadIdx],length);
1954 dummyReadIdx += length;
1955 }
1956
1957
1686 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ 1958 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/