Mercurial > public > ostc4
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****/ |