# HG changeset patch # User heinrichsweikamp # Date 1585574171 0 # Node ID b3f684cea9c0854ffb0d0b10b51bfd9afbc291ee # Parent 9a9e4908ce2e2194357380c4b20081b18c00251a# Parent 2effe85f1a9be3b3de7aa2832f95a8ab772b1720 Merged in Ideenmodellierer/ostc4/minor_improvments (pull request #41) Minor improvments diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Inc/configuration.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Inc/configuration.h Mon Mar 30 13:16:11 2020 +0000 @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Inc/configuration.h +/// \brief Header file for variant specific firmware adaptations at compile time +/// \author heinrichs weikamp gmbh +/// \date 29-February-2020 +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2020 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see . +////////////////////////////////////////////////////////////////////////////// + + +#ifndef CONFIGURATION_HEADER +#define CONFIGURATION_HEADER + +/* Enable this to make the simulator write a logbook entry */ +/* #define SIM_WRITES_LOGBOOK 1 */ + +/* Enable this for support of optical bottle pressure interface */ +/* #define ENABLE_BOTTLE_SENSOR */ + +/* Enable this to show voltage in parallel to charge state */ +/* #define ALWAYS_SHOW_VOLTAGE */ + +/* Enable this to skip coplete scan of dive log during startup */ +/* #define TRUST_LOG_CONSISTENCY */ + +/* Enable this to reset the profile data by pressing enter within log info menu */ +/* #define ENABLE_PROFILE_RESET */ + +#endif diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Inc/externLogbookFlash.h --- a/Discovery/Inc/externLogbookFlash.h Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Inc/externLogbookFlash.h Mon Mar 30 13:16:11 2020 +0000 @@ -149,7 +149,7 @@ void ext_flash_enable_protection(void); void ext_flash_read_block_start(void); - +uint8_t ext_dive_log_consistent(void); void ext_flash_repair_dive_log(void); uint8_t ext_flash_erase_firmware_if_not_empty(void); @@ -165,5 +165,6 @@ uint32_t ext_flash_AnalyseSampleBuffer(char *pstrResult); void ext_flash_CloseSector(void); +void ext_flash_invalidate_sample_index(uint32_t sectorStart); #endif /* EXTERN_LOGBOOK_FLASH_H */ diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Inc/logbook.h --- a/Discovery/Inc/logbook.h Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Inc/logbook.h Mon Mar 30 13:16:11 2020 +0000 @@ -30,6 +30,8 @@ #include "data_central.h" #include "settings.h" +#define NUM_GAS (5) /* number of selectable gases */ + typedef struct { uint8_t setpoint_cbar; @@ -65,7 +67,7 @@ int16_t minTemp; uint16_t surfacePressure_mbar; uint16_t desaturationTime; - SGasListLog gasordil[5]; + SGasListLog gasordil[NUM_GAS]; uint8_t firmwareVersionLow; uint8_t firmwareVersionHigh; uint16_t batteryVoltage; @@ -73,7 +75,7 @@ uint8_t gfAtBeginning; uint8_t gfAtEnd; uint16_t personalDiveCount; - SSetpointLog setpoint[5]; + SSetpointLog setpoint[NUM_GAS]; uint16_t maxCNS; uint16_t averageDepth_mbar; uint16_t total_diveTime_seconds; @@ -114,7 +116,7 @@ uint8_t minTemp[2]; uint8_t surfacePressure_mbar[2]; uint8_t desaturationTime[2]; - uint8_t gasordil[5*4]; + uint8_t gasordil[NUM_GAS*4]; uint8_t firmwareVersionLow; uint8_t firmwareVersionHigh; uint8_t batteryVoltage[2]; @@ -209,11 +211,15 @@ uint8_t logbook_getNumberOfHeaders(void); uint8_t logbook_getHeader(uint8_t StepBackwards,SLogbookHeader* pLogbookHeader); -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); +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, uint16_t* tank); void logbook_test(void); void logbook_InitAndWrite(const SDiveState* pStateReal); void logbook_recover_brokenlog(uint8_t headerId); uint16_t logbook_lastDive_diveNumber(void); +uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader); +void logbook_readDummySamples(uint8_t* pTarget, uint16_t length); #endif /* LOGBOOK_H */ diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Inc/t7.h --- a/Discovery/Inc/t7.h Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Inc/t7.h Mon Mar 30 13:16:11 2020 +0000 @@ -31,6 +31,26 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" #include "gfx_engine.h" +#include "configuration.h" + + +typedef enum +{ + LLC_Empty = 0, + LLC_Temperature, + LLC_AverageDepth, + LLC_ppO2, + LLC_Stopwatch, + LLC_Ceiling, + LLC_FutureTTS, + LLC_CNS, + LLC_GF, +#ifdef ENABLE_BOTTLE_SENSOR + LCC_BottleBar, +#endif + LLC_END + +} customview_llc_t; /* Exported functions --------------------------------------------------------*/ void t7_init(void); diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/base.c --- a/Discovery/Src/base.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/base.c Mon Mar 30 13:16:11 2020 +0000 @@ -199,6 +199,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stdio.h" #include // for memcopy +#include "configuration.h" #include "stm32f4xx_hal.h" #include "ostc.h" @@ -327,12 +328,6 @@ return(ch); } */ -/* #define DEBUG_RUNTIME TRUE */ -#ifdef DEBUG_RUNTIME -#define MEASURECNT 60 /* number of measuremets to be stored */ -static uint32_t loopcnt[MEASURECNT]; -#endif - static uint8_t ButtonAction = ACTION_END; static void StoreButtonAction(uint8_t action) @@ -350,11 +345,6 @@ { uint32_t pLayerInvisible; uint16_t totalDiveCounterFound; -#ifdef DEBUG_RUNTIME - RTC_TimeTypeDef Stime; - uint8_t measurementindex = 0; - uint8_t lastsecond = 0xFF; -#endif SStateList status; detectionState_t pitchstate; @@ -445,9 +435,16 @@ GFX_logoAutoOff(); EXTILine_Buttons_Config(); +#ifdef TRUST_LOG_CONSISTENCY + if(!ext_dive_log_consistent()) /* only repair log if an invalid entry was detected */ + { + ext_flash_repair_dive_log(); + } + +#else /* always check and repair log */ ext_flash_repair_dive_log(); //ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(1); - +#endif totalDiveCounterFound = logbook_lastDive_diveNumber(); if( settingsGetPointer()->totalDiveCounter < totalDiveCounterFound ) settingsGetPointer()->totalDiveCounter = totalDiveCounterFound; @@ -527,9 +524,6 @@ } -// Enable this to make the simulator write a logbook entry -// #define SIM_WRITES_LOGBOOK 1 - #ifdef SIM_WRITES_LOGBOOK if(stateUsed == stateSimGetPointer()) logbook_InitAndWrite(stateUsed); @@ -537,27 +531,6 @@ if(stateUsed == stateRealGetPointer()) /* Handle log entries while in dive mode*/ logbook_InitAndWrite(stateUsed); } - -#ifdef DEBUG_RUNTIME - translateTime(stateUsed->lifeData.timeBinaryFormat, &Stime); - if(lastsecond == 0xFF) - { - measurementindex = 0; - loopcnt[measurementindex] = 0; - lastsecond = Stime.Seconds; - } - loopcnt[measurementindex]++; - - if(lastsecond != Stime.Seconds) - { - measurementindex++; - if (measurementindex == MEASURECNT) measurementindex = 0; - loopcnt[measurementindex] = 0; - lastsecond = Stime.Seconds; - if(measurementindex +1 < MEASURECNT) loopcnt[measurementindex +1] = 0xffff; /* helps to identify the latest value */ - } -#endif - } } diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/data_exchange_main.c --- a/Discovery/Src/data_exchange_main.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/data_exchange_main.c Mon Mar 30 13:16:11 2020 +0000 @@ -764,6 +764,7 @@ // wireless - �ltere daten aufr�umen +#if 0 for(int i=0;i<(2*NUM_GASES+1);i++) { if(pStateReal->lifeData.bottle_bar[i]) @@ -777,7 +778,12 @@ pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] += 100; } } - +#else + if(stateRealGetPointer()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings] < 6000) /* max age after ten minutes */ + { + stateRealGetPointerWrite()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings]++; + } +#endif if(!DataEX_check_header_and_footer_ok()) { if(DataEX_check_header_and_footer_devicedata()) diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/externLogbookFlash.c --- a/Discovery/Src/externLogbookFlash.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/externLogbookFlash.c Mon Mar 30 13:16:11 2020 +0000 @@ -787,6 +787,7 @@ actualAddress = SAMPLESTART; } preparedPageAddress = actualAddress; + ext_flash_invalidate_sample_index(preparedPageAddress); ext_flash_erase64kB(); actualAddress = actualAdressBackup; } @@ -1353,6 +1354,40 @@ } */ +uint8_t ext_dive_log_consistent(void) +{ + uint8_t ret = 0; + uint8_t header1, header2; + uint8_t id; + convert_Type dataStart; + + SSettings *settings = settingsGetPointer(); + id = settings->lastDiveLogId; + + actualAddress = HEADERSTART + (0x800 * id); + ext_flash_read_block_start(); + ext_flash_read_block(&header1, EF_HEADER); + ext_flash_read_block(&header2, EF_HEADER); + dataStart.u8bit.byteHigh = 0; + ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); + ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); + ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); + ext_flash_read_block_stop(); + if((header1 == 0xFA) && (header2 == 0xFA)) /* Header is indicating the start of a dive */ + { + actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; + ext_flash_read_block_start(); + ext_flash_read_block(&header1, EF_HEADER); + ext_flash_read_block(&header2, EF_HEADER); + ext_flash_read_block_stop(); + if((header1 == 0xFA) && (header2 == 0xFA)) /* Secondary header was written at the end of a dive */ + { + ret = 1; /* => lastDiveLogID points to a valid dive entry */ + } + } + return ret; +} + // =============================================================================== // ext_flash_repair_dive_log /// @brief This function @@ -1361,6 +1396,7 @@ /// and /// lastDiveLogId /// + void ext_flash_repair_dive_log(void) { uint8_t header1, header2; @@ -1760,7 +1796,12 @@ actualAddress = ringStart; if(do_not_erase == 0) - ext_flash_erase_if_on_page_start(); + { + if((ext_flash_erase_if_on_page_start()) && (type == EF_SAMPLE)) /* invalidate header sample information if needed */ + { + ext_flash_invalidate_sample_index(actualAddress); + } + } while( ilastDiveLogId + 1; + convert_Type dataStart, dataEnd; + + uint32_t HeaderAddrBackup = actualPointerHeader; + + while(diveidx != settings->lastDiveLogId) + { + actualAddress = HEADERSTART + (0x800 * diveidx) + HEADER2OFFSET; + ext_flash_read_block_start(); + ext_flash_read_block(&header1, EF_HEADER); + ext_flash_read_block(&header2, EF_HEADER); + dataStart.u8bit.byteHigh = 0; + ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); + ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); + ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); + dataEnd.u8bit.byteHigh = 0; + ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER); + ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER); + ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER); + ext_flash_read_block_stop(); + + if((header1 == 0xFA) && (header2 == 0xFA)) /* Dive ID is in use */ + { + if(((dataStart.u32bit >= sectorStart) && (dataStart.u32bit <= sectorStart+0xFFFF)) /* Sample start is within erased sector */ + || ((dataEnd.u32bit >= sectorStart) && (dataEnd.u32bit <= sectorStart+0xFFFF))) /* End of sample data is within erased sector */ + { + actualAddress = HEADERSTART + (0x800 * diveidx) + HEADER2OFFSET; + ext_flash_incf_address(EF_HEADER); /* skip header bytes */ + ext_flash_incf_address(EF_HEADER); + actualPointerHeader = actualAddress; + ef_write_block(emptySamples,9,EF_HEADER,1); /* clear start, stop and length data */ + actualPointerHeader = HeaderAddrBackup; + } + } + diveidx++; + } +} + + + /* uint8_t ext_flash_erase_firmware_if_not_empty(void) { diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/logbook.c --- a/Discovery/Src/logbook.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/logbook.c Mon Mar 30 13:16:11 2020 +0000 @@ -56,15 +56,16 @@ #include "data_exchange.h" #include "decom.h" #include "tHome.h" // for tHome_findNextStop() +#include "settings.h" +#include "configuration.h" /* Private types -------------------------------------------------------------*/ -#define NUM_GASES 5 - #define LOGBOOK_VERSION (0x30) #define LOGBOOK_VERSION_OSTC3 (0x24) #define DEFAULT_SAMPLES (100) /* Number of sample data bytes in case of an broken header information */ +#define DUMMY_SAMPLES (1000) /* Maximum number of samples profided by a dummy dive profile */ typedef struct /* don't forget to adjust void clear_divisor(void) */ { @@ -87,6 +88,12 @@ static SDivisor divisor; static SDivisor divisorBackup; +static SSmallHeader smallDummyHeader; +static uint16_t dummyWriteIdx; +static uint16_t dummyReadIdx; +static uint8_t dummyMemoryBuffer[1000*4]; + + /* Private function prototypes -----------------------------------------------*/ static void clear_divisor(void); static void logbook_SetAverageDepth(float average_depth_meter); @@ -96,6 +103,7 @@ static void logbook_SetLastStop(float last_stop_depth_bar); static void logbook_writedata(void * data, int length_byte); static void logbook_UpdateHeader(const SDiveState * pStateReal); +static void logbook_createDummyProfile(SLogbookHeader* pHeader, uint16_t length, uint16_t* depth, int16_t* temperature, uint16_t* ppo2); /* Exported functions --------------------------------------------------------*/ @@ -308,9 +316,13 @@ smallHeader.cnsDivisor = 12; smallHeader.tankType = 6; +#ifdef ENABLE_BOTTLE_SENSOR + smallHeader.tankLength = 2; + smallHeader.tankDivisor = 30; /* log tank data once a minute */ +#else smallHeader.tankLength = 0; smallHeader.tankDivisor = 0; - +#endif logbook_writedata((void *) &smallHeader,sizeof(smallHeader)); clear_divisor(); @@ -516,6 +528,7 @@ length += 1; sample[length] = 0; length += 1; + pDecoinfo = &stateUsed->decolistBuehlmann; /* use GF per default if something went wrong */ } if(pDecoinfo->output_ndl_seconds > 0) @@ -624,6 +637,22 @@ divisor.cns--; } +#ifdef ENABLE_BOTTLE_SENSOR + if(smallHeader.tankDivisor) + { + if(divisor.tank == 0) + { + divisor.tank = smallHeader.tankDivisor - 1; + addS16(&sample[length], ((state->lifeData.bottle_bar[state->lifeData.actualGas.GasIdInSettings]))); + length += smallHeader.tankLength; + } + else + { + divisor.tank--; + } + } +#endif + profileByteFlag.uw = length - 3; if(eventByte1.uw) { @@ -649,7 +678,8 @@ * @param int32_t* cns: output Value * @return bytes read / 0 = reading Error */ -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) +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, uint16_t* tank) { int length = 0; _Bool bEvent = 0; @@ -678,6 +708,9 @@ *setpoint_cbar = -1; if(bailout) *bailout = -1; + if(tank) + *tank = 0; + if(manualGas) { manualGas->percentageO2 =-1; @@ -868,6 +901,27 @@ divisor.cns--; } +#ifdef ENABLE_BOTTLE_SENSOR + if(smallHeader.tankDivisor) + { + if(divisor.tank == 0) + { + divisor.tank = smallHeader.tankDivisor - 1; + ext_flash_read_next_sample_part( (uint8_t*)&temp, 2); + bytesRead +=2; + length -= 2; + if(tank) + { + *tank = (uint16_t)temp; + } + } + else + { + divisor.tank--; + } + } +#endif + if (length != 0) return 0; @@ -890,18 +944,20 @@ * @param int32_t* cns : output array * @return length of output */ -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) +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, uint16_t* tank) { //Test read //SLogbookHeader header; //logbook_getHeader(&header); SLogbookHeader header; - int iNum; - int firstgasid = 0; - int retVal = 0; - int compression = 0; - int i; + int16_t iNum; + int16_t firstgasid = 0; + uint16_t retVal = 0; + int16_t compression = 0; + int16_t i; // uint32_t diveTime_seconds; int32_t depthVal = 0; int16_t gasidVal = 0; @@ -922,13 +978,15 @@ int32_t temperatureLast = 0; int32_t temperatureFirst = 0; int32_t cnsLast = 0; - int16_t decostepDepthVal = 0; - int16_t decostepDepthLast = 0; + int16_t decostepDepthVal = 0; + int16_t decostepDepthLast = 0; + uint16_t tankVal = 0; SManualGas manualGasVal; SManualGas manualGasLast; manualGasLast.percentageO2 = 0; manualGasLast.percentageHe = 0; + uint16_t numSamples = 0; float ambiant_pressure_bar = 0; float ppO2 = 0; @@ -946,8 +1004,11 @@ //diveTime_seconds = header.diveTime_seconds ; for(compression = 1; compression < 100; compression ++) { - if((header.total_diveTime_seconds / header.samplingRate)/compression <= length) - break; + numSamples = (header.total_diveTime_seconds / header.samplingRate)/compression; + if(numSamples <= length) + { + break; + } } @@ -971,6 +1032,8 @@ sensor3[i] = 0; if(cns) cns[i] = 0; + if(tank) + tank[i] = 0; } //We start with fist gasid gasidLast = firstgasid; @@ -988,135 +1051,149 @@ iNum = 0; int counter = 0; temperatureLast = -1000; - while ((bytesRead < totalNumberOfBytes) && (iNum < length)) - { - ext_flash_set_entry_point(); - divisorBackup = divisor; - retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, &decostepDepthVal); - - if(retVal == 0) - { - //Error try to read again!!! - ext_flash_reopen_read_sample_at_entry_point(); - divisor = divisorBackup; - retVal = readSample(&depthVal,&gasidVal,&setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, &decostepDepthVal); - - if(retVal == 0) - break; - } - bytesRead +=retVal; - - //if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value - if(depthVal == -1) - depthVal = depthLast; - else - depthLast = depthVal; + if(totalNumberOfBytes > 2) /* read real data */ + { + while ((bytesRead < totalNumberOfBytes) && (iNum < length)) + { + ext_flash_set_entry_point(); + divisorBackup = divisor; + retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, + &bailoutVal, &decostepDepthVal, &tankVal); - if(gasidVal == -1) - gasidVal = gasidLast; - else - gasidLast = gasidVal; - - if(temperatureVal == -1000) - temperatureVal = temperatureLast; - else - { - if(temperatureLast == -1000) - temperatureFirst = temperatureVal; - temperatureLast = temperatureVal; - } - - if(setPointVal == -1) - setPointVal = setPointLast; - else - setPointLast = setPointVal; - - if(sensor1Val == -1) - sensor1Val = sensor1Last; - else - sensor1Last = sensor1Val; - - if(sensor2Val == -1) - sensor2Val = sensor2Last; - else - sensor2Last = sensor2Val; + if(retVal == 0) + { + //Error try to read again!!! + ext_flash_reopen_read_sample_at_entry_point(); + divisor = divisorBackup; + retVal = readSample(&depthVal,&gasidVal,&setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, + &manualGasVal, &bailoutVal, &decostepDepthVal, &tankVal); - if(sensor3Val == -1) - sensor3Val = sensor3Last; - else - sensor3Last = sensor3Val; - - if(cnsVal == -1) - cnsVal = cnsLast; - else - cnsLast = cnsVal; + if(retVal == 0) + break; + } + bytesRead +=retVal; - if(manualGasVal.percentageO2 == -1) - manualGasVal = manualGasLast; - else - manualGasLast = manualGasVal; - - if(bailoutVal == -1) - bailoutVal = bailoutLast; - else - bailoutLast = bailoutVal; + //if for some variable no new value is in the sample for (z.B. gasidVal = -1), we take the last value + if(depthVal == -1) + depthVal = depthLast; + else + depthLast = depthVal; - if(decostepDepthVal == -1) - decostepDepthVal = decostepDepthLast; - else - decostepDepthLast = decostepDepthVal; - - counter++; - // Heed compression - // Write here to arrays - if(counter == compression) - { - if(depth) - depth[iNum] = depthVal; - if(gasid) - gasid[iNum] = gasidVal; - if(temperature) - temperature[iNum] = temperatureVal; - if(cns) - cns[iNum] = cnsVal; - if(bailout) - bailout[iNum] = bailoutVal; - if(decostopDepth) - decostopDepth[iNum] = decostepDepthVal; - - if(ppo2) + if(gasidVal == -1) + gasidVal = gasidLast; + else + gasidLast = gasidVal; + + if(temperatureVal == -1000) + temperatureVal = temperatureLast; + else { - //Calc ppo2 - Values - SGas gas; - gas.setPoint_cbar = setPointVal; - if(gasidVal > 0) - { - gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage; - gas.nitrogen_percentage = 100 - gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage; - } - else - { - gas.helium_percentage = manualGasVal.percentageHe; - gas.nitrogen_percentage = 100 - gas.helium_percentage - manualGasVal.percentageO2; - } - ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000; - ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas ); - ppo2[iNum] = (uint16_t) ( ppO2 * 100); + if(temperatureLast == -1000) + temperatureFirst = temperatureVal; + temperatureLast = temperatureVal; } - if(setpoint) - setpoint[iNum] = setPointVal; + if(setPointVal == -1) + setPointVal = setPointLast; + else + setPointLast = setPointVal; + + if(sensor1Val == -1) + sensor1Val = sensor1Last; + else + sensor1Last = sensor1Val; + + if(sensor2Val == -1) + sensor2Val = sensor2Last; + else + sensor2Last = sensor2Val; + + if(sensor3Val == -1) + sensor3Val = sensor3Last; + else + sensor3Last = sensor3Val; + + if(cnsVal == -1) + cnsVal = cnsLast; + else + cnsLast = cnsVal; + + if(manualGasVal.percentageO2 == -1) + manualGasVal = manualGasLast; + else + manualGasLast = manualGasVal; + + if(bailoutVal == -1) + bailoutVal = bailoutLast; + else + bailoutLast = bailoutVal; + + if(decostepDepthVal == -1) + decostepDepthVal = decostepDepthLast; + else + decostepDepthLast = decostepDepthVal; - if(sensor1) - sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF; - if(sensor2) - sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF; - if(sensor3) - sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF; - iNum++; - counter = 0; - } - } + counter++; + // Heed compression + // Write here to arrays + if(counter == compression) + { + if(depth) + depth[iNum] = depthVal; + if(gasid) + gasid[iNum] = gasidVal; + if(temperature) + temperature[iNum] = temperatureVal; + if(cns) + cns[iNum] = cnsVal; + if(bailout) + bailout[iNum] = bailoutVal; + if(decostopDepth) + decostopDepth[iNum] = decostepDepthVal; + + if(ppo2) + { + //Calc ppo2 - Values + SGas gas; + gas.setPoint_cbar = setPointVal; + if(gasidVal > 0) + { + gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage; + gas.nitrogen_percentage = 100 - gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage; + } + else + { + gas.helium_percentage = manualGasVal.percentageHe; + gas.nitrogen_percentage = 100 - gas.helium_percentage - manualGasVal.percentageO2; + } + ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000; + ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas ); + ppo2[iNum] = (uint16_t) ( ppO2 * 100); + } + + if(tank) + { + tank[iNum] = tankVal; + } + if(setpoint) + setpoint[iNum] = setPointVal; + + if(sensor1) + sensor1[iNum] = (sensor1Val / 0xFFFF) & 0xFF; + if(sensor2) + sensor2[iNum] = (sensor2Val / 0xFFFF) & 0xFF; + if(sensor3) + sensor3[iNum] = (sensor3Val / 0xFFFF) & 0xFF; + iNum++; + counter = 0; + } + } + } + else + { + logbook_createDummyProfile(&header, numSamples, depth, temperature, ppo2); + iNum = numSamples; + } // Fix first Temperature Entries 150930 hw if(temperature) @@ -1382,6 +1459,7 @@ SLogbookHeaderOSTC3 * logbook_build_ostc3header(SLogbookHeader* pHead) { convert_Type data,data2; + uint16_t dummyLength = 0; memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2); memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3); @@ -1398,22 +1476,34 @@ data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; - /* check if sample address information are corrupted by address range. */ - /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ - if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) + if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */ + &&(pHead->pBeginProfileData[1] == 0) + &&(pHead->pBeginProfileData[2] == 0)) { - data2.u32bit = data.u32bit + DEFAULT_SAMPLES; - pHead->pEndProfileData[0] = data2.u8bit.byteLow; - pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; - pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; - data.u32bit = DEFAULT_SAMPLES; + dummyLength = logbook_fillDummySampleBuffer(pHead); + + data2.u32bit = data.u32bit + dummyLength; /* calc new end address (which is equal to dummyLength) */ + data.u32bit = data2.u32bit; /* data is used below to represent the length */ } else { - data.u8bit.byteHigh = 0; - data.u8bit.byteLow = pHead->profileLength[0]; - data.u8bit.byteMidLow = pHead->profileLength[1]; - data.u8bit.byteMidHigh = pHead->profileLength[2]; + /* check if sample address information are corrupted by address range. */ + /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ + if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) + { + data2.u32bit = data.u32bit + DEFAULT_SAMPLES; + pHead->pEndProfileData[0] = data2.u8bit.byteLow; + pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; + pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; + data.u32bit = DEFAULT_SAMPLES; + } + else + { + data.u8bit.byteHigh = 0; + data.u8bit.byteLow = pHead->profileLength[0]; + data.u8bit.byteMidLow = pHead->profileLength[1]; + data.u8bit.byteMidHigh = pHead->profileLength[2]; + } } if(data.u32bit != 0xFFFFFF) data.u32bit += 3; @@ -1529,6 +1619,7 @@ SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead) { convert_Type data, data2; + uint32_t dummyLength = 0; data.u8bit.byteHigh = 0; @@ -1541,24 +1632,35 @@ data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; - /* check if sample address information are corrupted by address range. */ - /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ - if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) + if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */ + &&(pHead->pBeginProfileData[1] == 0) + &&(pHead->pBeginProfileData[2] == 0)) { - data2.u32bit = data.u32bit + DEFAULT_SAMPLES; - pHead->pEndProfileData[0] = data2.u8bit.byteLow; - pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; - pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; - data.u32bit = DEFAULT_SAMPLES; + dummyLength = logbook_fillDummySampleBuffer(pHead); + + data2.u32bit = data.u32bit + dummyLength; /* calc new end address (which is equal to dummyLength) */ + data.u32bit = data2.u32bit; /* data is used below to represent the length */ } else { - data.u8bit.byteHigh = 0; - data.u8bit.byteLow = pHead->profileLength[0]; - data.u8bit.byteMidLow = pHead->profileLength[1]; - data.u8bit.byteMidHigh = pHead->profileLength[2]; + /* check if sample address information are corrupted by address range. */ + /* TODO: Workaround. Better solution would be to check end of ring for 0xFF pattern */ + if((data.u32bit > data2.u32bit) && (data.u32bit < (SAMPLESTOP - 0x9000))) + { + data2.u32bit = data.u32bit + DEFAULT_SAMPLES; + pHead->pEndProfileData[0] = data2.u8bit.byteLow; + pHead->pEndProfileData[1] = data2.u8bit.byteMidLow; + pHead->pEndProfileData[2] = data2.u8bit.byteMidHigh; + data.u32bit = DEFAULT_SAMPLES; + } + else + { + data.u8bit.byteHigh = 0; + data.u8bit.byteLow = pHead->profileLength[0]; + data.u8bit.byteMidLow = pHead->profileLength[1]; + data.u8bit.byteMidHigh = pHead->profileLength[2]; + } } - if(data.u32bit != 0xFFFFFF) { data.u32bit += 3; @@ -1640,20 +1742,20 @@ ext_flash_set_entry_point(); divisorBackup = divisor; - retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); + retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL); if(retVal == 0) { //Error try to read again!!! ext_flash_reopen_read_sample_at_entry_point(); divisor = divisorBackup; - retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); + retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL); if(retVal == 0) { //Error try to read again!!! ext_flash_reopen_read_sample_at_entry_point(); divisor = divisorBackup; - retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL); + retVal = readSample(&depthVal,&gasidVal, &setPointVal, &temperatureVal, &sensor1Val, &sensor2Val, &sensor3Val, &cnsVal, &manualGasVal, &bailoutVal, NULL, NULL); if(retVal == 0) { @@ -1684,4 +1786,213 @@ ext_flash_close_new_dive_log((uint8_t *)&header); } +void logbook_createDummyProfile(SLogbookHeader* pHeader, uint16_t length, uint16_t* depth, int16_t* temperature, uint16_t* ppo2) +{ + uint8_t drawDeco = 1; + uint16_t index = 0; + uint16_t indexDescenStop = 0; + uint16_t indexAscendStart = 0; + uint16_t simDecentDepth = 0; + uint16_t simDecentStep = 0; + uint16_t simAcentDepth = 0; + uint16_t simAcentStep = 0; + float ambiant_pressure_bar = 0; + + simDecentStep = pHeader->maxDepth / (length / 6); /* first 1/6 for descend */ + simAcentStep = pHeader->maxDepth / (length / 3); /* first 1/3 for ascend */ + + SGas gas; + + + if(ppo2) + { + /* find first gas ID */ + for(index = 0; index < NUM_GAS; index++) + { + if(pHeader->gasordil[index].note.ub.first) + break; + } + if(index != NUM_GAS) + { + gas.helium_percentage = pHeader->gasordil[index].helium_percentage; + gas.nitrogen_percentage = 100 - gas.helium_percentage - pHeader->gasordil[index].oxygen_percentage; + } + } + + while((index < length) && (simDecentDepth < pHeader->maxDepth)) /* draw decent */ + { + depth[index] = simDecentDepth; + temperature[index] = pHeader->minTemp; + if(ppo2) + { + ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000; + ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100); + } + index++; + simDecentDepth += simDecentStep; + } + indexDescenStop = index; + index = length -1; + while((index > indexDescenStop) && (simAcentDepth < pHeader->maxDepth)) /* draw ascend including max deco stop */ + { + depth[index] = simAcentDepth; + temperature[index] = pHeader->minTemp; + if(ppo2) + { + ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000; + ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100); + } + if((drawDeco) && (simAcentDepth < pHeader->lastDecostop_m)) /* draw deco step */ + { + drawDeco = length / 10; + while(drawDeco) + { + index--; + depth[index] = simAcentDepth; + temperature[index] = pHeader->minTemp; + if(ppo2) + { + ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000; + ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100); + } + drawDeco--; + } + } + index--; + simAcentDepth += simAcentStep; + } + indexAscendStart = index; + index = indexDescenStop; + while(index <= indexAscendStart) /* draw isobar dive phase */ + { + depth[index] = pHeader->maxDepth; + temperature[index] = pHeader->minTemp; + if(ppo2) + { + ambiant_pressure_bar =((float)(depth[index] + pHeader->surfacePressure_mbar))/1000; + ppo2[index] = (uint16_t) ((decom_calc_ppO2(ambiant_pressure_bar, &gas )) * 100); + } + index++; + } +} + +void logbook_resetDummy() +{ + dummyWriteIdx = 0; + dummyReadIdx = 0; +} + +void logbook_writeDummy(void* data, uint16_t length) +{ + memcpy(&dummyMemoryBuffer[dummyWriteIdx],(uint8_t *)data, length); + dummyWriteIdx += length; +} +void logbook_writeDummySample(uint16_t depth, int16_t temperature) +{ + uint8_t sample[10]; + int length = 0; + + int i = 0; + for(i = 0; i <10 ;i++) sample[i] = 0; + addU16(sample, depth); + length += 2; + sample[2] = 0; + length++; + + if(divisor.temperature == 0) + { + divisor.temperature = smallHeader.tempDivisor - 1; + addS16(&sample[length], temperature); + length += 2; + } + else + { + divisor.temperature--; + } + + logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader)); +} + + +uint16_t logbook_fillDummySampleBuffer(SLogbookHeader* pHeader) +{ + uint16_t depthArray[DUMMY_SAMPLES]; + int16_t temperatureArray[DUMMY_SAMPLES]; + uint16_t ppo2Array[DUMMY_SAMPLES]; + + uint16_t index = 0; + uint16_t dummyBufferSize = 0; + uint16_t dummyProfileLength = 0; + uint32_t overallSecond = pHeader->diveTimeMinutes * 60 + pHeader->diveTimeSeconds; + + logbook_resetDummy(); + clear_divisor(); + + smallDummyHeader.profileLength[0] = 0xFF; + smallDummyHeader.profileLength[1] = 0xFF; + smallDummyHeader.profileLength[2] = 0xFF; + smallDummyHeader.samplingRate_seconds = 2; + smallDummyHeader.numDivisors = 7; + + smallDummyHeader.tempType = 0; + smallDummyHeader.tempLength = 2; + smallDummyHeader.tempDivisor = 6; + + smallDummyHeader.deco_ndlType = 1; + smallDummyHeader.deco_ndlLength = 2; + smallDummyHeader.deco_ndlDivisor = 0; + + /* GF in % at actual position */ + smallDummyHeader.gfType = 2; + smallDummyHeader.gfLength = 1; + smallDummyHeader.gfDivisor = 0; + + /* 3 Sensors: 8bit ppO2 in 0.01bar, 16bit voltage in 0,1mV */ + smallDummyHeader.ppo2Type = 3; + smallDummyHeader.ppo2Length = 9; + smallDummyHeader.ppo2Divisor = 0; + + /* last 15 stops in minutes (last, second_to_last, ... */ + /* last stop depth is defined in header */ + smallDummyHeader.decoplanType = 4; + smallDummyHeader.decoplanLength = 15; + smallDummyHeader.decoplanDivisor = 0; + + smallDummyHeader.cnsType = 5; + smallDummyHeader.cnsLength = 2; + smallDummyHeader.cnsDivisor = 0; + + smallDummyHeader.tankType = 6; + smallDummyHeader.tankLength = 2; + smallDummyHeader.tankDivisor = 0; + + if((overallSecond / smallDummyHeader.samplingRate_seconds) > DUMMY_SAMPLES) /* reduce sample interval to keep buffer size */ + { + smallDummyHeader.samplingRate_seconds = overallSecond / DUMMY_SAMPLES; + dummyProfileLength = DUMMY_SAMPLES; + } + else + { + dummyProfileLength = overallSecond / smallDummyHeader.samplingRate_seconds; + } + logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader)); + logbook_createDummyProfile(pHeader,dummyProfileLength, depthArray, temperatureArray, ppo2Array ); + + for (index = 0; index < dummyProfileLength; index++) + { + logbook_writeDummySample(depthArray[index], temperatureArray[index]); + } + + dummyBufferSize = dummyWriteIdx; + + return dummyBufferSize; /* return size of dummy buffer */ +} + +void logbook_readDummySamples(uint8_t* pTarget, uint16_t length) +{ + memcpy(pTarget,&dummyMemoryBuffer[dummyReadIdx],length); + dummyReadIdx += length; +} + + /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/settings.c --- a/Discovery/Src/settings.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/settings.c Mon Mar 30 13:16:11 2020 +0000 @@ -33,6 +33,7 @@ #include "text_multilanguage.h" // for LANGUAGE_END #include "tHome.h" // for CVIEW_END #include "motion.h" +#include "t7.h" SSettings Settings; @@ -275,7 +276,7 @@ .scooterSPARE2[0] = 0, .ppo2sensors_deactivated = 0, .tX_colorscheme = 0, - .tX_userselectedLeftLowerCornerPrimary = 1, + .tX_userselectedLeftLowerCornerPrimary = LLC_Temperature, .tX_userselectedLeftLowerCornerTimeout = 0, .tX_customViewPrimary = 1, .tX_customViewTimeout = 0, @@ -1161,9 +1162,9 @@ /* uint8_t tX_userselectedLeftLowerCornerPrimary; */ - if(Settings.tX_userselectedLeftLowerCornerPrimary > 8) + if(Settings.tX_userselectedLeftLowerCornerPrimary >= LLC_END) { - Settings.tX_userselectedLeftLowerCornerPrimary = 1; + Settings.tX_userselectedLeftLowerCornerPrimary = LLC_Temperature; corrections++; } diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/show_logbook.c --- a/Discovery/Src/show_logbook.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/show_logbook.c Mon Mar 30 13:16:11 2020 +0000 @@ -33,6 +33,7 @@ #include "gfx_fonts.h" #include "show_logbook.h" #include "unit.h" +#include "configuration.h" #include #include @@ -425,9 +426,16 @@ uint16_t depthdata[1000] = { 0 }; uint8_t gasdata[1000] = { 0 }; int16_t tempdata[1000] = { 0 }; + uint16_t tankdata[1000] = { 0 }; + +#ifdef ENABLE_BOTTLE_SENSOR + uint16_t bottlePressureStart = 0; + uint16_t bottlePressureEnd = 0; + uint16_t loop = 0; +#endif uint16_t dataLength = 0; - dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tankdata); //Print Date uint8_t year = logbookHeader.dateYear; @@ -450,7 +458,7 @@ if(logNumber > 9999) logNumber = 9999; - snprintf(text,20,"#%i",logNumber); + snprintf(text,20,"#%ld",logNumber); Gfx_write_label_var(hgfx, 300, 590,10, &FontT42,CLUT_GasSensor1,text); } @@ -620,7 +628,25 @@ snprintf(text,40,"%i\016\016 hPa\017",logbookHeader.surfacePressure_mbar); Gfx_write_label_var(hgfx,320,600,440, &FontT42,CLUT_GasSensor1,text); - +/* Show tank info */ +#ifdef ENABLE_BOTTLE_SENSOR + for(loop = 0; loop < dataLength; loop++) + { + if((bottlePressureStart == 0) && (tankdata[loop] != 0)) /* find first pressure value */ + { + bottlePressureStart = tankdata[loop]; + } + if((tankdata[loop] != 0)) /* store last pressure value */ + { + bottlePressureEnd = tankdata[loop]; + } + } + if(bottlePressureStart != 0) + { + snprintf(text,40,"%i | %i\016\016 Bar\017",bottlePressureStart,bottlePressureEnd); + Gfx_write_label_var(hgfx,600,800,440, &FontT42,CLUT_GasSensor1,text); + } +#endif //--- print coordinate system & depth graph with gaschanges --- wintemp.left = 330; wintemp.top = 160; @@ -651,7 +677,7 @@ uint16_t decoDepthdata[1000]; uint16_t *pDecoDepthData = 0; - dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, decoDepthdata); + dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, tempdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, decoDepthdata, NULL); for(int i = 0; ilifeData.temperature_celsius = stateRealGetPointer()->lifeData.temperature_celsius; pDiveState->lifeData.compass_heading = stateRealGetPointer()->lifeData.compass_heading; pDiveState->lifeData.battery_charge = stateRealGetPointer()->lifeData.battery_charge; - +#ifdef ENABLE_BOTTLE_SENSOR + pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = stateRealGetPointer()->lifeData.bottle_bar[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings]; + pDiveState->lifeData.bottle_bar_age_MilliSeconds[pDiveState->lifeData.actualGas.GasIdInSettings] = stateRealGetPointer()->lifeData.bottle_bar_age_MilliSeconds[stateRealGetPointer()->lifeData.actualGas.GasIdInSettings]; +#endif int now = current_second(); if( last_second == now) return; diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/t7.c --- a/Discovery/Src/t7.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/t7.c Mon Mar 30 13:16:11 2020 +0000 @@ -91,8 +91,7 @@ GFX_DrawCfgWindow t7pCompass; GFX_DrawCfgWindow t7surfaceL, t7surfaceR; -uint8_t selection_custom_field = 1; -uint8_t selection_customview = 1; +uint8_t selection_customview = LLC_Temperature; uint8_t updateNecessary = 0; @@ -139,6 +138,9 @@ CVIEW_END }; + +static uint8_t selection_custom_field = LLC_Temperature; + const uint8_t *customviewsDive = customviewsDiveStandard; const uint8_t *customviewsSurface = customviewsSurfaceStandard; @@ -171,7 +173,7 @@ SSettings* pSettings; pSettings = settingsGetPointer(); - selection_custom_field = 1; + selection_custom_field = LLC_Temperature; selection_customview = customviewsSurface[0]; t7screen.FBStartAdress = 0; @@ -682,7 +684,9 @@ uint8_t dateNotSet = 0; uint8_t oxygen_percentage, gasOffset, actualGasID; -// uint16_t bottleFirstGas_bar; +#ifdef ENABLE_BOTTLE_SENSOR + uint16_t bottleFirstGas_bar; +#endif point_t start, stop;//, other; SSettings* pSettings; @@ -1005,14 +1009,15 @@ GFX_write_string(&FontT48,&t7surfaceL,text,7); actualGasID = stateUsed->lifeData.actualGas.GasIdInSettings; - /* + +#ifdef ENABLE_BOTTLE_SENSOR bottleFirstGas_bar = stateUsed->lifeData.bottle_bar[actualGasID]; if(bottleFirstGas_bar) { snprintf(text,255,"%3u\022\016\016 bar",bottleFirstGas_bar); GFX_write_string(&FontT48,&t7surfaceL,text,8); } - */ +#endif // after gas name :-) if(actualGasID > gasOffset) // security { @@ -1089,8 +1094,12 @@ GFX_write_string_color(&Batt24,&t7batt,text,0,CLUT_WarningRed); if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140)) { +#ifdef ALWAYS_SHOW_VOLTAGE // show battery percent and voltage snprintf(text,16,"\f\002%u%% \f%.1fV",(uint8_t)stateUsed->lifeData.battery_charge,stateUsed->lifeData.battery_voltage); +#else + snprintf(text,16,"\004\025\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge); +#endif if(warning_count_high_time) text[0] = '\a'; GFX_write_string(&FontT24,&t7voltage,text,0); @@ -1107,9 +1116,12 @@ if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140)) { +#ifdef ALWAYS_SHOW_VOLTAGE // show battery percent and voltage snprintf(text,16,"\f\002%u%% \f%.1fV",(uint8_t)stateUsed->lifeData.battery_charge,stateUsed->lifeData.battery_voltage); - // GFX_write_string(&FontT24,&t7batt,text,0); +#else + snprintf(text,16,"\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge); +#endif GFX_write_string(&FontT24,&t7voltage,text,0); } else @@ -2521,18 +2533,17 @@ void t7_change_field(void) { - const uint8_t minVal = 0; - const uint8_t maxValGF = 8; - const uint8_t maxValVPM = 7; - uint8_t maxNow = maxValGF; - selection_custom_field++; - if(stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE) - maxNow = maxValVPM; - - if(selection_custom_field > maxNow) - selection_custom_field = minVal; + if((stateUsed->diveSettings.deco_type.ub.standard == VPM_MODE) && (selection_custom_field == LLC_GF)) /* no GF if in VPM mode */ + { + selection_custom_field++; + } + + if(selection_custom_field >= LLC_END) + { + selection_custom_field = LLC_Empty; + } } @@ -2546,6 +2557,9 @@ uint8_t textpointer = 0; _Bool tinyHeaderFont = 0; uint8_t line = 0; +#ifdef ENABLE_BOTTLE_SENSOR + uint16_t agedColor = 0; +#endif SDivetime Stopwatch = {0,0,0,0}; float fAverageDepth, fAverageDepthAbsolute; @@ -2577,7 +2591,7 @@ switch(selection_custom_field) { /* Temperature */ - case 1: + case LLC_Temperature: default: temperature = unit_temperature_float(stateUsed->lifeData.temperature_celsius); headerText[2] = TXT_Temperature; @@ -2591,7 +2605,7 @@ break; /* Average Depth */ - case 2: + case LLC_AverageDepth: headerText[2] = TXT_AvgDepth; if(settingsGetPointer()->nonMetricalSystem) snprintf(text,TEXTSIZE,"\020%01.0f",unit_depth_float(fAverageDepthAbsolute)); @@ -2600,13 +2614,13 @@ break; /* ppO2 */ - case 3: + case LLC_ppO2: headerText[2] = TXT_ppO2; snprintf(text,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2); break; /* Stop Uhr */ - case 4: + case LLC_Stopwatch: headerText[2] = TXT_Stopwatch; if(settingsGetPointer()->nonMetricalSystem) snprintf(text,TEXTSIZE,"\020\016\016%u:%02u\n\r%01.0f",Stopwatch.Minutes, Stopwatch.Seconds,unit_depth_float(fAverageDepth)); @@ -2617,7 +2631,7 @@ break; /* Ceiling */ - case 5: + case LLC_Ceiling: headerText[2] = TXT_Ceiling; if((pDecoinfoStandard->output_ceiling_meter > 99.9f) || (settingsGetPointer()->nonMetricalSystem)) snprintf(text,TEXTSIZE,"\020%01.0f",unit_depth_float(pDecoinfoStandard->output_ceiling_meter)); @@ -2626,7 +2640,7 @@ break; /* Future TTS */ - case 6: + case LLC_FutureTTS: headerText[2] = TXT_FutureTTS; if (pDecoinfoFuture->output_time_to_surface_seconds < 1000 * 60) snprintf(text,TEXTSIZE,"\020\016\016@+%u'\n\r" "%i' TTS",settingsGetPointer()->future_TTS, (pDecoinfoFuture->output_time_to_surface_seconds + 59) / 60); @@ -2637,7 +2651,7 @@ break; /* CNS */ - case 7: + case LLC_CNS: headerText[2] = TXT_CNS; fCNS = stateUsed->lifeData .cns; if(fCNS > 999) @@ -2646,10 +2660,17 @@ break; /* actual GF */ - case 8: + case LLC_GF: headerText[2] = TXT_ActualGradient; snprintf(text,TEXTSIZE,"\020%.0f\016\016%%\017",100 * pDecoinfoStandard->super_saturation); break; +#ifdef ENABLE_BOTTLE_SENSOR + case LCC_BottleBar: + headerText[2] = TXT_AtemGasVorrat; + tinyHeaderFont = 1; + snprintf(text,TEXTSIZE,"%d\016\016\017", stateUsed->lifeData.bottle_bar[stateUsed->lifeData.actualGas.GasIdInSettings]); + break; +#endif } headerText[3] = 0; @@ -2659,7 +2680,38 @@ GFX_write_string(&FontT42,&t7l3,headerText,0); t7_colorscheme_mod(text); - GFX_write_string(&FontT105,&t7l3,text,line); +#ifndef ENABLE_BOTTLE_SENSOR + GFX_write_string(&FontT105,&t7l3,text,line); +#else + if(selection_custom_field != LCC_BottleBar) /* a changing color set is used for bar display */ + { + GFX_write_string(&FontT105,&t7l3,text,line); + } + else + { + agedColor = stateUsed->lifeData.bottle_bar_age_MilliSeconds[stateUsed->lifeData.actualGas.GasIdInSettings]; + if(agedColor > 1200) + { + agedColor = CLUT_WarningRed; + } + else + if(agedColor > 600) + { + agedColor = CLUT_MenuLineUnselected; + } + else + if(agedColor > 20) + { + agedColor = CLUT_Font031; + } + else + { + agedColor = CLUT_Font020; + } + + GFX_write_string_color(&FontT105,&t7l3,text,line,agedColor); + } +#endif } /* Private functions ---------------------------------------------------------*/ diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/tCCR.c --- a/Discovery/Src/tCCR.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/tCCR.c Mon Mar 30 13:16:11 2020 +0000 @@ -33,6 +33,7 @@ #include "data_central.h" #include "data_exchange.h" #include "check_warning.h" +#include "configuration.h" /* Private types -------------------------------------------------------------*/ typedef struct @@ -52,6 +53,8 @@ #define HUD_RX_START_DELAY_MS (500u) /* Delay for start of RX function to avoid start of reception while a transmission is ongoing. */ /* Based on an assumed cycle time by the sensor of 1 second. Started at time of last RX */ +#define BOTTLE_SENSOR_TIMEOUT (6000u) /* signal pressure budget as not received after 10 minutes (6000 * 100ms) */ + /* Private variables ---------------------------------------------------------*/ static SIrLink receiveHUD[2]; static uint8_t boolHUDdata = 0; @@ -289,7 +292,15 @@ void tCCR_init(void) { + uint8_t loop; + StartListeningToUART_HUD = 1; + + SDiveState* pDiveData = stateRealGetPointerWrite(); + for(loop=0;loop<(2*NUM_GASES+1);loop++) + { + pDiveData->lifeData.bottle_bar_age_MilliSeconds[loop] = BOTTLE_SENSOR_TIMEOUT; + } } @@ -350,6 +361,10 @@ void tCCR_control(void) { + uint16_t checksum = 0; +#ifdef ENABLE_BOTTLE_SENSOR + SDiveState *pLivedata = stateRealGetPointerWrite(); +#endif if((UartReadyHUD == RESET) && StartListeningToUART_HUD && (time_elapsed_ms(LastReceivedTick_HUD, HAL_GetTick()) > HUD_RX_START_DELAY_MS)) { @@ -362,31 +377,41 @@ UartReadyHUD = RESET; StartListeningToUART_HUD = 1; - memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11); - receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]); - receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]); - - uint16_t checksum = 0; + /* check if received package is valid */ + for(int i=0;i<13;i++) + { + checksum += receiveHUDraw[i]; + } + receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]); + if(checksum == receiveHUD[!boolHUDdata].checksum) + { +#ifdef ENABLE_BOTTLE_SENSOR + if(receiveHUDraw[0] == 0xA5) /* code for pressure sensor */ + { + pLivedata->lifeData.bottle_bar[pLivedata->lifeData.actualGas.GasIdInSettings] = receiveHUDraw[10]; + pLivedata->lifeData.bottle_bar_age_MilliSeconds[pLivedata->lifeData.actualGas.GasIdInSettings] = 0; + } + else +#endif + /* handle O2 sensor data */ + { + memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11); + receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]); + } - for(int i=0;i<13;i++) - { - checksum += receiveHUDraw[i]; - } - if(checksum == receiveHUD[!boolHUDdata].checksum) - { - boolHUDdata = !boolHUDdata; - HUDTimeoutCount = 0; - data_old__lost_connection_to_HUD = 0; - } - else - { - if(data_old__lost_connection_to_HUD) /* we lost connection, maybe due to RX shift => start single byte read to resynchronize */ - { - HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1); - StartListeningToUART_HUD = 0; - } - } - memset(receiveHUDraw,0,sizeof(receiveHUDraw)); + boolHUDdata = !boolHUDdata; + HUDTimeoutCount = 0; + data_old__lost_connection_to_HUD = 0; + } + else + { + if(data_old__lost_connection_to_HUD) /* we lost connection, maybe due to RX shift => start single byte read to resynchronize */ + { + HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 1); + StartListeningToUART_HUD = 0; + } + } + memset(receiveHUDraw,0,sizeof(receiveHUDraw)); } } diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/tComm.c --- a/Discovery/Src/tComm.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/tComm.c Mon Mar 30 13:16:11 2020 +0000 @@ -583,7 +583,6 @@ #else uint8_t dummyForBootloader[256] = {0}; #endif - uint8_t count; uint8_t aTxBuffer[128]; uint8_t aRxBuffer[68]; @@ -1182,21 +1181,45 @@ plogbookHeaderOSTC3 = logbook_build_ostc3header(&logbookHeader); if(HAL_UART_Transmit(&UartHandle, (uint8_t*)plogbookHeaderOSTC3, 256,5000)!= HAL_OK) return 0; - ext_flash_open_read_sample(255 - aRxBuffer[0], &sampleTotalLength); - while(sampleTotalLength >= 128) + + if((logbookHeader.pBeginProfileData[0]==0) /* no sample information */ + && (logbookHeader.pBeginProfileData[1]==0) + && (logbookHeader.pBeginProfileData[2]==0)) { - ext_flash_read_next_sample_part(aTxBuffer,128); - sampleTotalLength -= 128; - if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK) - return 0; + sampleTotalLength = logbook_fillDummySampleBuffer(&logbookHeader); + while(sampleTotalLength >= 128) + { + logbook_readDummySamples(aTxBuffer,128); + sampleTotalLength -= 128; + if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK) + return 0; + } + if(sampleTotalLength) + { + logbook_readDummySamples(aTxBuffer,sampleTotalLength); + if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK) + return 0; + } + } - if(sampleTotalLength) + else { - ext_flash_read_next_sample_part(aTxBuffer,sampleTotalLength); - if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK) - return 0; + ext_flash_open_read_sample(255 - aRxBuffer[0], &sampleTotalLength); + while(sampleTotalLength >= 128) + { + ext_flash_read_next_sample_part(aTxBuffer,128); + sampleTotalLength -= 128; + if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, 128,5000)!= HAL_OK) + return 0; + } + if(sampleTotalLength) + { + ext_flash_read_next_sample_part(aTxBuffer,sampleTotalLength); + if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK) + return 0; + } } - aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); + aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); break; // read min,default,max setting diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/tInfoLog.c --- a/Discovery/Src/tInfoLog.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/tInfoLog.c Mon Mar 30 13:16:11 2020 +0000 @@ -36,6 +36,8 @@ #include "tInfo.h" #include "tMenu.h" #include "unit.h" +#include "externLogbookFlash.h" +#include "configuration.h" /* Exported variables --------------------------------------------------------*/ @@ -64,6 +66,9 @@ void stepBackInfo(void); void stepForwardInfo(void); void showLogExit(void); +#ifdef ENABLE_PROFILE_RESET +void resetDiveProfile(void); +#endif /* Exported functions --------------------------------------------------------*/ void tInfoLog_init(void) @@ -176,6 +181,9 @@ switch(sendAction) { case ACTION_BUTTON_ENTER: +#ifdef ENABLE_PROFILE_RESET + resetDiveProfile(); +#endif break; case ACTION_BUTTON_NEXT: showNextLogPage(); @@ -429,4 +437,21 @@ show_logbook_test(0, stepBack); } +#ifdef ENABLE_PROFILE_RESET +void resetDiveProfile() +{ + uint8_t stepBack; + SLogbookHeader logbookHeader; + convert_Type dataStart; + stepBack = (6 * (infolog.page - 1)) + infolog.line - 1; /* calculate current dive ID */ + logbook_getHeader(stepBack ,&logbookHeader); + dataStart.u8bit.byteHigh = 0; + dataStart.u8bit.byteLow = logbookHeader.pBeginProfileData[0]; + dataStart.u8bit.byteMidLow = logbookHeader.pBeginProfileData[1]; + dataStart.u8bit.byteMidHigh = logbookHeader.pBeginProfileData[2]; + + dataStart.u32bit &= 0xFFFF0000; /* set to sector start */ + ext_flash_invalidate_sample_index(dataStart.u32bit); +} +#endif diff -r 9a9e4908ce2e -r b3f684cea9c0 Discovery/Src/tMenuEditSystem.c --- a/Discovery/Src/tMenuEditSystem.c Sun Mar 01 10:06:45 2020 +0100 +++ b/Discovery/Src/tMenuEditSystem.c Mon Mar 30 13:16:11 2020 +0000 @@ -876,38 +876,43 @@ switch(settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary) { /* Temperature */ - case 1: + case LLC_Temperature: text[4] = TXT_Temperature; break; /* Average Depth */ - case 2: + case LLC_AverageDepth: text[4] = TXT_AvgDepth; break; /* ppO2 */ - case 3: + case LLC_ppO2: text[4] = TXT_ppO2; break; /* Stop Uhr */ - case 4: + case LLC_Stopwatch: text[4] = TXT_Stopwatch; break; /* Ceiling */ - case 5: + case LLC_Ceiling: text[4] = TXT_Ceiling; break; /* Future TTS */ - case 6: + case LLC_FutureTTS: text[4] = TXT_FutureTTS; break; /* CNS */ - case 7: + case LLC_CNS: text[4] = TXT_CNS; break; - case 8: + case LLC_GF: text[4] = TXT_ActualGradient; break; +#ifdef ENABLE_BOTTLE_SENSOR + case LCC_BottleBar: + text[4] = TXT_AtemGasVorrat; + break; +#endif /* none */ - case 0: + case LLC_Empty: text[4] = '-'; break; default: @@ -1080,7 +1085,7 @@ value += 1; - if(value > 8) + if(value >= LLC_END) value = 0; settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary = value;