# HG changeset patch # User heinrichsweikamp # Date 1586934071 0 # Node ID dd0d0952ef35eaafa8adeda9aed67df97697da20 # Parent dddfe79171319304d0f8368fbe8b3d20c3cdfa38# Parent 04d94851cd1b102c404ae85a20329aaccc9ec8c7 Merged in Ideenmodellierer/ostc4/Improve_Logtansfer (pull request #42) Improve Logtansfer diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Inc/configuration.h --- a/Discovery/Inc/configuration.h Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Inc/configuration.h Wed Apr 15 07:01:11 2020 +0000 @@ -40,7 +40,10 @@ /* 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 */ +/* Enable this to transfer additional data list last dive ID and last sample index during raw data requests */ +/* define SEND_DATA_DETAILS */ + +/* Enable to activate a menu item in reset menu which provide sample ring analysis / repair functionality */ +/* #define ENABLE_ANALYSE_SAMPLES */ #endif diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Inc/externLogbookFlash.h --- a/Discovery/Inc/externLogbookFlash.h Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Inc/externLogbookFlash.h Wed Apr 15 07:01:11 2020 +0000 @@ -141,6 +141,9 @@ void ext_flash_read_header_memory(uint8_t *data); void ext_flash_write_header_memory(uint8_t *data); +void ext_flash_read_sample_memory(uint8_t *data,uint16_t blockId); +void ext_flash_write_sample_memory(uint8_t *data,uint16_t blockId); + void ext_flash_erase_logbook(void); void ext_flash_erase_chip(void); void ext_flash_erase_firmware(void); @@ -165,6 +168,9 @@ uint32_t ext_flash_AnalyseSampleBuffer(char *pstrResult); void ext_flash_CloseSector(void); -void ext_flash_invalidate_sample_index(uint32_t sectorStart); + +uint32_t ext_flash_read_profilelength_small_header(uint32_t smallHeaderAddr); +uint8_t ext_flash_SampleOverrunValid(void); + #endif /* EXTERN_LOGBOOK_FLASH_H */ diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Src/externLogbookFlash.c --- a/Discovery/Src/externLogbookFlash.c Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Src/externLogbookFlash.c Wed Apr 15 07:01:11 2020 +0000 @@ -787,7 +787,6 @@ actualAddress = SAMPLESTART; } preparedPageAddress = actualAddress; - ext_flash_invalidate_sample_index(preparedPageAddress); ext_flash_erase64kB(); actualAddress = actualAdressBackup; } @@ -972,7 +971,7 @@ // =============================================================================== -// ext_flash_read_header_memory +// ext_flash_write_header_memory /// @brief This function erases and overwrites the entire logbook header block /// @date 04-April-2016 /// @@ -985,6 +984,24 @@ ef_write_block(data, 0x40000, EF_HEADER, 0); } +void ext_flash_read_sample_memory(uint8_t *data,uint16_t blockId) +{ + actualAddress = SAMPLESTART; + actualAddress += blockId * 0x8000; /* add 32k Block offset */ + actualPointerSample = actualAddress; + ext_flash_read_block_start(); + ext_flash_read_block_multi(data, 0x8000, EF_SAMPLE); + ext_flash_read_block_stop(); +} + +void ext_flash_write_sample_memory(uint8_t *data,uint16_t blockId) +{ + actualAddress = SAMPLESTART; + actualAddress += blockId * 0x8000; /* add 32k Block offset */ + actualPointerSample = actualAddress; + ef_write_block(data, 0x8000, EF_SAMPLE,0); +} + void ext_flash_open_read_sample(uint8_t StepBackwards, uint32_t *totalNumberOfBytes) { @@ -1797,10 +1814,7 @@ if(do_not_erase == 0) { - if((ext_flash_erase_if_on_page_start()) && (type == EF_SAMPLE)) /* invalidate header sample information if needed */ - { - ext_flash_invalidate_sample_index(actualAddress); - } + ext_flash_erase_if_on_page_start(); } 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++; - } + uint32_t profileLength = 0; + actualPointerSample = smallHeaderAddr; + actualAddress = actualPointerSample; + ext_flash_read_block_start(); + ext_flash_read_next_sample_part((uint8_t*)&profileLength, 3); + ext_flash_close_read_sample(); + return profileLength; } - /* uint8_t ext_flash_erase_firmware_if_not_empty(void) { diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Src/logbook.c --- a/Discovery/Src/logbook.c Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Src/logbook.c Wed Apr 15 07:01:11 2020 +0000 @@ -91,7 +91,7 @@ static SSmallHeader smallDummyHeader; static uint16_t dummyWriteIdx; static uint16_t dummyReadIdx; -static uint8_t dummyMemoryBuffer[1000*4]; +static uint8_t dummyMemoryBuffer[5000]; /* Private function prototypes -----------------------------------------------*/ @@ -981,6 +981,7 @@ int16_t decostepDepthVal = 0; int16_t decostepDepthLast = 0; uint16_t tankVal = 0; + uint32_t small_profileLength = 0; SManualGas manualGasVal; SManualGas manualGasLast; @@ -1040,8 +1041,8 @@ //uint16_t* ppo2, uint16_t* cns# - uint32_t totalNumberOfBytes = 0; - uint32_t bytesRead = 0; + uint32_t totalNumberOfBytes = 0; + uint32_t bytesRead = 0; ext_flash_open_read_sample( StepBackwards,&totalNumberOfBytes); ext_flash_read_next_sample_part((uint8_t*)&smallHeader, sizeof(SSmallHeader)); bytesRead += sizeof(SSmallHeader); @@ -1051,7 +1052,10 @@ iNum = 0; int counter = 0; temperatureLast = -1000; - if(totalNumberOfBytes > 2) /* read real data */ + + small_profileLength = (smallHeader.profileLength[2] << 16) + (smallHeader.profileLength[1] << 8) + smallHeader.profileLength[0]; + + if(totalNumberOfBytes == small_profileLength) /* sizes provided by header and small header are the same => real data */ { while ((bytesRead < totalNumberOfBytes) && (iNum < length)) { @@ -1460,152 +1464,174 @@ { convert_Type data,data2; uint16_t dummyLength = 0; + uint8_t returnEmptyHeader = 0; - memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2); - memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3); - memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3); + uint32_t headerProfileLength, sampleProfileLength, sampleProfileStart; - data.u8bit.byteHigh = 0; - data.u8bit.byteLow = pHead->pBeginProfileData[0]; - data.u8bit.byteMidLow = pHead->pBeginProfileData[1]; - data.u8bit.byteMidHigh = pHead->pBeginProfileData[2]; - - data2.u8bit.byteHigh = 0; - data2.u8bit.byteLow = pHead->pEndProfileData[0]; - data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; - data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; - - if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */ - &&(pHead->pBeginProfileData[1] == 0) - &&(pHead->pBeginProfileData[2] == 0)) + if(pHead->diveHeaderStart != 0xFAFA) { - 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 */ + returnEmptyHeader = 1; } else { - /* 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))) + memcpy(headerOSTC3.diveHeaderStart, &pHead->diveHeaderStart, 2); + memcpy(headerOSTC3.pBeginProfileData, &pHead->pBeginProfileData, 3); + memcpy(headerOSTC3.pEndProfileData, &pHead->pEndProfileData, 3); + + data.u8bit.byteHigh = 0; + data.u8bit.byteLow = pHead->pBeginProfileData[0]; + data.u8bit.byteMidLow = pHead->pBeginProfileData[1]; + data.u8bit.byteMidHigh = pHead->pBeginProfileData[2]; + + sampleProfileStart = data.u32bit; + + data2.u8bit.byteHigh = 0; + data2.u8bit.byteLow = pHead->pEndProfileData[0]; + data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; + data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; + + 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) /* if the profile in use ? */ { - 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; + if(data2.u32bit < sampleProfileStart) /* Wrap around of sample ring detected */ + { + if(ext_flash_SampleOverrunValid() == 0) /* Wrap around does not seem to be valid => fallback */ + { + sampleProfileStart = 0; + } + } + if( sampleProfileStart == 0) /* should never happen unless OSTC with older debug version is in use (or invalid overrun) */ + { + sampleProfileLength = 1; + headerProfileLength = 2; + } + else + { + headerProfileLength = (pHead->profileLength[2] << 16) + (pHead->profileLength[1] << 8) + pHead->profileLength[0]; + sampleProfileLength = ext_flash_read_profilelength_small_header(sampleProfileStart); + } + + if(sampleProfileLength != headerProfileLength) + { + dummyLength = logbook_fillDummySampleBuffer(pHead); + + data2.u32bit = sampleProfileStart + dummyLength; /* calc new end address (which is equal to dummyLength) */ + data.u32bit = dummyLength; /* data is used below to represent the length */ + } + + data.u32bit += 3; + headerOSTC3.profileLength[0] = data.u8bit.byteLow; + headerOSTC3.profileLength[1] = data.u8bit.byteMidLow; + headerOSTC3.profileLength[2] = data.u8bit.byteMidHigh; + + memcpy(headerOSTC3.gasordil, pHead->gasordil, 20); + + if(pHead->logbookProfileVersion == LOGBOOK_VERSION) + { + headerOSTC3.logbookProfileVersion = LOGBOOK_VERSION_OSTC3; + memcpy(headerOSTC3.personalDiveCount, &pHead->personalDiveCount, 2); + headerOSTC3.safetyDistance_10cm = 0; + + for(int i=0;i<5;i++) + { + if(!pHead->gasordil[i].note.ub.active) + headerOSTC3.gasordil[3 + (i*4)] = 0; + else if(pHead->gasordil[i].note.ub.first) + { + /* depth = 0, note = 1 */ + headerOSTC3.gasordil[2 + (i*4)] = 0; + headerOSTC3.gasordil[3 + (i*4)] = 1; + } + else if( pHead->gasordil[i].depth_meter) + { + /* note = 3 */ + headerOSTC3.gasordil[3 + (i*4)] = 3; + } + } + } + else + { + headerOSTC3.logbookProfileVersion = 0xFF; + headerOSTC3.personalDiveCount[0] = 0xFF; + headerOSTC3.personalDiveCount[1] = 0xFF; + headerOSTC3.safetyDistance_10cm = 0xFF; + } + + headerOSTC3.dateYear = pHead->dateYear; + headerOSTC3.dateMonth = pHead->dateMonth; + headerOSTC3.dateDay = pHead->dateDay; + headerOSTC3.timeHour = pHead->timeHour; + headerOSTC3.timeMinute = pHead->timeMinute; + + memcpy(headerOSTC3.maxDepth, &pHead->maxDepth, 2); + memcpy(headerOSTC3.diveTimeMinutes, &pHead->diveTimeMinutes, 2); + + headerOSTC3.diveTimeSeconds = pHead->diveTimeSeconds; + + memcpy(headerOSTC3.minTemp, &pHead->minTemp, 2); + memcpy(headerOSTC3.surfacePressure_mbar,&pHead->surfacePressure_mbar, 2); + memcpy(headerOSTC3.desaturationTime, &pHead->desaturationTime, 2); + + headerOSTC3.firmwareVersionHigh = pHead->firmwareVersionHigh; + headerOSTC3.firmwareVersionLow = pHead->firmwareVersionLow; + + memcpy(headerOSTC3.batteryVoltage, &pHead->batteryVoltage, 2); + + headerOSTC3.samplingRate = pHead->samplingRate; + + memcpy(headerOSTC3.cnsAtBeginning, &pHead->cnsAtBeginning, 2); + + headerOSTC3.gfAtBeginning = pHead->gfAtBeginning; + headerOSTC3.gfAtEnd = pHead->gfAtEnd; + + memcpy(headerOSTC3.setpoint, pHead->setpoint, 10); + + headerOSTC3.salinity = pHead->salinity; + + memcpy(headerOSTC3.maxCNS, &pHead->maxCNS, 2); + memcpy(headerOSTC3.averageDepth_mbar, &pHead->averageDepth_mbar, 2); + memcpy(headerOSTC3.total_diveTime_seconds, &pHead->total_diveTime_seconds, 2); + + headerOSTC3.gfLow_or_Vpm_conservatism = pHead->gfLow_or_Vpm_conservatism; + headerOSTC3.gfHigh = pHead->gfHigh; + headerOSTC3.decoModel = pHead->decoModel; + + memcpy(headerOSTC3.diveNumber, &pHead->diveNumber, 2); + + headerOSTC3.diveMode = pHead->diveMode; + headerOSTC3.CCRmode = pHead->CCRmode; + + memcpy(headerOSTC3.n2CompartDesatTime_min,pHead->n2CompartDesatTime_min, 16); + memcpy(headerOSTC3.n2Compartments, pHead->n2Compartments, 64); + memcpy(headerOSTC3.heCompartDesatTime_min,pHead->heCompartDesatTime_min, 16); + memcpy(headerOSTC3.heCompartments, pHead->heCompartments, 64); + + headerOSTC3.lastDecostop_m = pHead->lastDecostop_m; + + memcpy(headerOSTC3.hwHudBattery_mV, &pHead->hwHudBattery_mV, 2); + + headerOSTC3.hwHudLastStatus = pHead->hwHudLastStatus; + + memcpy(headerOSTC3.batteryGaugeRegisters,&pHead->batteryGaugeRegisters, 6); + + + memcpy(headerOSTC3.diveHeaderEnd, &pHead->diveHeaderEnd, 2); } 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; - - headerOSTC3.profileLength[0] = data.u8bit.byteLow; - headerOSTC3.profileLength[1] = data.u8bit.byteMidLow; - headerOSTC3.profileLength[2] = data.u8bit.byteMidHigh; - - memcpy(headerOSTC3.gasordil, pHead->gasordil, 20); - - if(pHead->logbookProfileVersion == LOGBOOK_VERSION) - { - headerOSTC3.logbookProfileVersion = LOGBOOK_VERSION_OSTC3; - memcpy(headerOSTC3.personalDiveCount, &pHead->personalDiveCount, 2); - headerOSTC3.safetyDistance_10cm = 0; - - for(int i=0;i<5;i++) - { - if(!pHead->gasordil[i].note.ub.active) - headerOSTC3.gasordil[3 + (i*4)] = 0; - else if(pHead->gasordil[i].note.ub.first) - { - /* depth = 0, note = 1 */ - headerOSTC3.gasordil[2 + (i*4)] = 0; - headerOSTC3.gasordil[3 + (i*4)] = 1; - } - else if( pHead->gasordil[i].depth_meter) - { - /* note = 3 */ - headerOSTC3.gasordil[3 + (i*4)] = 3; - } + returnEmptyHeader = 1; } } - else + if(returnEmptyHeader) /* profile not in use => return array full of 0xFF */ { - headerOSTC3.logbookProfileVersion = 0xFF; - headerOSTC3.personalDiveCount[0] = 0xFF; - headerOSTC3.personalDiveCount[1] = 0xFF; - headerOSTC3.safetyDistance_10cm = 0xFF; + memset(&headerOSTC3, 0xFF, sizeof(headerOSTC3)); } - headerOSTC3.dateYear = pHead->dateYear; - headerOSTC3.dateMonth = pHead->dateMonth; - headerOSTC3.dateDay = pHead->dateDay; - headerOSTC3.timeHour = pHead->timeHour; - headerOSTC3.timeMinute = pHead->timeMinute; - - - memcpy(headerOSTC3.maxDepth, &pHead->maxDepth, 2); - memcpy(headerOSTC3.diveTimeMinutes, &pHead->diveTimeMinutes, 2); - - headerOSTC3.diveTimeSeconds = pHead->diveTimeSeconds; - - memcpy(headerOSTC3.minTemp, &pHead->minTemp, 2); - memcpy(headerOSTC3.surfacePressure_mbar,&pHead->surfacePressure_mbar, 2); - memcpy(headerOSTC3.desaturationTime, &pHead->desaturationTime, 2); - - headerOSTC3.firmwareVersionHigh = pHead->firmwareVersionHigh; - headerOSTC3.firmwareVersionLow = pHead->firmwareVersionLow; - - memcpy(headerOSTC3.batteryVoltage, &pHead->batteryVoltage, 2); - - headerOSTC3.samplingRate = pHead->samplingRate; - - memcpy(headerOSTC3.cnsAtBeginning, &pHead->cnsAtBeginning, 2); - - headerOSTC3.gfAtBeginning = pHead->gfAtBeginning; - headerOSTC3.gfAtEnd = pHead->gfAtEnd; - - memcpy(headerOSTC3.setpoint, pHead->setpoint, 10); - - headerOSTC3.salinity = pHead->salinity; - - memcpy(headerOSTC3.maxCNS, &pHead->maxCNS, 2); - memcpy(headerOSTC3.averageDepth_mbar, &pHead->averageDepth_mbar, 2); - memcpy(headerOSTC3.total_diveTime_seconds,&pHead->total_diveTime_seconds, 2); - - headerOSTC3.gfLow_or_Vpm_conservatism = pHead->gfLow_or_Vpm_conservatism; - headerOSTC3.gfHigh = pHead->gfHigh; - headerOSTC3.decoModel = pHead->decoModel; - - memcpy(headerOSTC3.diveNumber, &pHead->diveNumber, 2); - - headerOSTC3.diveMode = pHead->diveMode; - headerOSTC3.CCRmode = pHead->CCRmode; - - memcpy(headerOSTC3.n2CompartDesatTime_min,pHead->n2CompartDesatTime_min, 16); - memcpy(headerOSTC3.n2Compartments, pHead->n2Compartments, 64); - memcpy(headerOSTC3.heCompartDesatTime_min,pHead->heCompartDesatTime_min, 16); - memcpy(headerOSTC3.heCompartments, pHead->heCompartments, 64); - - headerOSTC3.lastDecostop_m = pHead->lastDecostop_m; - - memcpy(headerOSTC3.hwHudBattery_mV, &pHead->hwHudBattery_mV, 2); - - headerOSTC3.hwHudLastStatus = pHead->hwHudLastStatus; - - memcpy(headerOSTC3.batteryGaugeRegisters,&pHead->batteryGaugeRegisters, 6); - - - memcpy(headerOSTC3.diveHeaderEnd, &pHead->diveHeaderEnd, 2); - return &headerOSTC3; } @@ -1618,74 +1644,86 @@ *********************************************************************************/ SLogbookHeaderOSTC3compact * logbook_build_ostc3header_compact(SLogbookHeader* pHead) { + uint8_t returnEmptyHeader = 0; convert_Type data, data2; uint32_t dummyLength = 0; - - - data.u8bit.byteHigh = 0; - data.u8bit.byteLow = pHead->pBeginProfileData[0]; - data.u8bit.byteMidLow = pHead->pBeginProfileData[1]; - data.u8bit.byteMidHigh = pHead->pBeginProfileData[2]; + uint32_t headerProfileLength, sampleProfileLength, sampleProfileStart; - data2.u8bit.byteHigh = 0; - data2.u8bit.byteLow = pHead->pEndProfileData[0]; - data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; - data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; - - if( (pHead->pBeginProfileData[0] == 0) /* no sample data available => use dummy */ - &&(pHead->pBeginProfileData[1] == 0) - &&(pHead->pBeginProfileData[2] == 0)) + if(pHead->diveHeaderStart != 0xFAFA) { - 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 */ + returnEmptyHeader = 1; } else { - /* 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))) + data.u8bit.byteHigh = 0; + data.u8bit.byteLow = pHead->pBeginProfileData[0]; + data.u8bit.byteMidLow = pHead->pBeginProfileData[1]; + data.u8bit.byteMidHigh = pHead->pBeginProfileData[2]; + + sampleProfileStart = data.u32bit; + + data2.u8bit.byteHigh = 0; + data2.u8bit.byteLow = pHead->pEndProfileData[0]; + data2.u8bit.byteMidLow = pHead->pEndProfileData[1]; + data2.u8bit.byteMidHigh = pHead->pEndProfileData[2]; + + 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) { - 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; + if(data2.u32bit < sampleProfileStart) /* Wrap around of sample ring detected */ + { + if(ext_flash_SampleOverrunValid() == 0) /* Wrap around does not seem to be valid => fallback */ + { + sampleProfileStart = 0; + } + } + + if( sampleProfileStart == 0) /* no sample data available => use dummy */ + { + sampleProfileLength = 1; + headerProfileLength = 2; + } + else + { + headerProfileLength = (pHead->profileLength[2] << 16) + (pHead->profileLength[1] << 8) + pHead->profileLength[0]; + sampleProfileLength = ext_flash_read_profilelength_small_header(sampleProfileStart); + } + if(sampleProfileLength != headerProfileLength) + { + dummyLength = logbook_fillDummySampleBuffer(pHead); + + data2.u32bit = sampleProfileStart + dummyLength; /* calc new end address (which is equal to dummyLength) */ + data.u32bit = dummyLength; /* data is used below to represent the length */ + } + data.u32bit += 3; + headerOSTC3compact.profileLength[0] = data.u8bit.byteLow; + headerOSTC3compact.profileLength[1] = data.u8bit.byteMidLow; + headerOSTC3compact.profileLength[2] = data.u8bit.byteMidHigh; + + headerOSTC3compact.dateYear = pHead->dateYear; + headerOSTC3compact.dateMonth = pHead->dateMonth; + headerOSTC3compact.dateDay = pHead->dateDay; + headerOSTC3compact.timeHour = pHead->timeHour; + headerOSTC3compact.timeMinute = pHead->timeMinute; + + memcpy(headerOSTC3compact.maxDepth, &pHead->maxDepth, 2); + memcpy(headerOSTC3compact.diveTimeMinutes, &pHead->diveTimeMinutes, 2); + + headerOSTC3compact.diveTimeSeconds = pHead->diveTimeSeconds; + headerOSTC3compact.totalDiveNumberLow = pHead->diveNumber & 0xFF; + headerOSTC3compact.totalDiveNumberHigh = (uint8_t)(pHead->diveNumber/256); + headerOSTC3compact.profileVersion = 0x24; // Logbook-Profile version, 0x24 = date and time is start not end } else { - data.u8bit.byteHigh = 0; - data.u8bit.byteLow = pHead->profileLength[0]; - data.u8bit.byteMidLow = pHead->profileLength[1]; - data.u8bit.byteMidHigh = pHead->profileLength[2]; + returnEmptyHeader = 1; } } - if(data.u32bit != 0xFFFFFF) - { - data.u32bit += 3; - - headerOSTC3compact.profileLength[0] = data.u8bit.byteLow; - headerOSTC3compact.profileLength[1] = data.u8bit.byteMidLow; - headerOSTC3compact.profileLength[2] = data.u8bit.byteMidHigh; - - headerOSTC3compact.dateYear = pHead->dateYear; - headerOSTC3compact.dateMonth = pHead->dateMonth; - headerOSTC3compact.dateDay = pHead->dateDay; - headerOSTC3compact.timeHour = pHead->timeHour; - headerOSTC3compact.timeMinute = pHead->timeMinute; - - memcpy(headerOSTC3compact.maxDepth, &pHead->maxDepth, 2); - memcpy(headerOSTC3compact.diveTimeMinutes, &pHead->diveTimeMinutes, 2); - - headerOSTC3compact.diveTimeSeconds = pHead->diveTimeSeconds; - - - headerOSTC3compact.totalDiveNumberLow = pHead->diveNumber & 0xFF; - headerOSTC3compact.totalDiveNumberHigh = (uint8_t)(pHead->diveNumber/256); - headerOSTC3compact.profileVersion = 0x24; // Logbook-Profile version, 0x24 = date and time is start not end - } - else + if(returnEmptyHeader) { memset(&headerOSTC3compact, 0xFF, sizeof(SLogbookHeaderOSTC3compact)); } @@ -1910,7 +1948,7 @@ divisor.temperature--; } - logbook_writeDummy((void *) &smallDummyHeader,sizeof(smallDummyHeader)); + logbook_writeDummy((void *) sample,length); } diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Src/tComm.c --- a/Discovery/Src/tComm.c Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Src/tComm.c Wed Apr 15 07:01:11 2020 +0000 @@ -589,6 +589,8 @@ uint8_t aTxBuffer[128]; uint8_t aRxBuffer[68]; uint8_t answer; + uint16_t index; + uint32_t header_profileLength, OSTC3_profileLength; aTxBuffer[0] = type; aTxBuffer[1] = prompt4D4C(receiveStartByteUart); uint8_t tempHigh, tempLow; @@ -665,6 +667,8 @@ case 0x85: // hw read entire logbook memory case 0x86: // hw overwrite entire logbook memory case 0x87: // hw ext_flash_repair_SPECIAL_dive_numbers_starting_count_with memory(x) + case 0x88: /* read entire sample memory */ + case 0x89: /* write entire sample memory */ #endif case 0xC1: // Start low-level bootloader @@ -885,14 +889,25 @@ for(int i=0;i<8;i++) HAL_UART_Transmit(&UartHandle, (uint8_t *)(logCopyDataPtr + (0x8000 * i)), (uint16_t)0x8000,60000); releaseFrame(98,logCopyDataPtr); +#ifdef SEND_DATA_DETAILS + HAL_UART_Transmit(&UartHandle, (uint8_t*)&pSettings->lastDiveLogId, 1,60000); +#endif break; case 0x86: aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); logCopyDataPtr = getFrame(98); for(int i=0;i<8;i++) + { HAL_UART_Receive(&UartHandle, (uint8_t *)(logCopyDataPtr + (0x8000 * i)), (uint16_t)0x8000,60000); + } ext_flash_write_header_memory((uint8_t *)logCopyDataPtr); +#ifdef SEND_DATA_DETAILS + if(HAL_UART_Receive(&UartHandle, (uint8_t *)(logCopyDataPtr + (0x8000 * 8)), (uint16_t)0x01,60000) == HAL_OK) /* receive lastlogID */ + { + pSettings->lastDiveLogId = *(uint8_t*)(logCopyDataPtr + (0x40000)); + } +#endif releaseFrame(98,logCopyDataPtr); break; @@ -906,6 +921,39 @@ ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(totalDiveCount.u16bit); aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); break; + case 0x88: + aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); + logCopyDataPtr = getFrame(98); + + for(index = 0; index <384; index++) /* transmit in 32k blocks */ + { + ext_flash_read_sample_memory((uint8_t *)logCopyDataPtr, index); + if(HAL_UART_Transmit(&UartHandle, (uint8_t *)(logCopyDataPtr), (uint16_t)0x8000,60000) != HAL_OK) + { + break; + } + } + releaseFrame(98,logCopyDataPtr); + HAL_UART_Transmit(&UartHandle, (uint8_t*)&pSettings->logFlashNextSampleStartAddress, 4,60000); /* send next sample pos */ + break; + case 0x89: + aTxBuffer[count++] = prompt4D4C(receiveStartByteUart); + logCopyDataPtr = getFrame(98); + + for(index = 0; index <384; index++) /* transmit in 32k blocks 384*/ + { + + if(HAL_UART_Receive(&UartHandle, (uint8_t *)(logCopyDataPtr), (uint16_t)0x8000,60000) != HAL_OK) + { + break; + } + ext_flash_write_sample_memory((uint8_t *)logCopyDataPtr, index); + } + + releaseFrame(98,logCopyDataPtr); + HAL_UART_Receive(&UartHandle, (uint8_t*)&pSettings->logFlashNextSampleStartAddress, 4,60000); /* send next sample pos */ + break; + #endif } @@ -1184,9 +1232,11 @@ if(HAL_UART_Transmit(&UartHandle, (uint8_t*)plogbookHeaderOSTC3, 256,5000)!= HAL_OK) return 0; - if((logbookHeader.pBeginProfileData[0]==0) /* no sample information */ - && (logbookHeader.pBeginProfileData[1]==0) - && (logbookHeader.pBeginProfileData[2]==0)) + OSTC3_profileLength = (plogbookHeaderOSTC3->profileLength[2] << 16) + (plogbookHeaderOSTC3->profileLength[1] << 8) + + plogbookHeaderOSTC3->profileLength[0] -3; + header_profileLength = (logbookHeader.profileLength[2] << 16) + (logbookHeader.profileLength[1] << 8) + logbookHeader.profileLength[0]; + + if(OSTC3_profileLength != header_profileLength) /* has headerdata been changed to dummy data? */ { sampleTotalLength = logbook_fillDummySampleBuffer(&logbookHeader); while(sampleTotalLength >= 128) @@ -1202,7 +1252,6 @@ if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, sampleTotalLength,5000)!= HAL_OK) return 0; } - } else { diff -r dddfe7917131 -r dd0d0952ef35 Discovery/Src/tInfoLog.c --- a/Discovery/Src/tInfoLog.c Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Src/tInfoLog.c Wed Apr 15 07:01:11 2020 +0000 @@ -66,9 +66,6 @@ void stepBackInfo(void); void stepForwardInfo(void); void showLogExit(void); -#ifdef ENABLE_PROFILE_RESET -void resetDiveProfile(void); -#endif /* Exported functions --------------------------------------------------------*/ void tInfoLog_init(void) @@ -181,9 +178,6 @@ switch(sendAction) { case ACTION_BUTTON_ENTER: -#ifdef ENABLE_PROFILE_RESET - resetDiveProfile(); -#endif break; case ACTION_BUTTON_NEXT: showNextLogPage(); @@ -437,21 +431,3 @@ 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 dddfe7917131 -r dd0d0952ef35 Discovery/Src/tMenuEditSystem.c --- a/Discovery/Src/tMenuEditSystem.c Wed Apr 08 16:34:54 2020 +0200 +++ b/Discovery/Src/tMenuEditSystem.c Wed Apr 15 07:01:11 2020 +0000 @@ -41,9 +41,6 @@ #include "motion.h" #include "t7.h" -/* Uncomment to activate a menu item in reset menu which provide sample ring analysis / repair functionality */ -#define ENABLE_ANALYSE_SAMPLES - #define CV_SUBPAGE_MAX (2u) /* max number of customer view selection pages */ /*#define HAVE_DEBUG_VIEW */ static uint8_t infoPage = 0; @@ -97,7 +94,9 @@ uint8_t OnAction_LogbookOffset(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_SetFactoryDefaults(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_SetBatteryCharge(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#ifdef ENABLE_ANALYSE_SAMPLES uint8_t OnAction_RecoverSampleIdx(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#endif #ifdef SCREENTEST uint8_t OnAction_ScreenTest (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); #endif @@ -1635,18 +1634,18 @@ return EXIT_TO_MENU; } - +#ifdef ENABLE_ANALYSE_SAMPLES uint8_t OnAction_RecoverSampleIdx(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) { char text[32]; char strResult[20]; - ext_flash_AnalyseSampleBuffer(strResult); snprintf(&text[0],30,"Ring: %s",strResult); //"Code: %X",settingsGetPointer()->logFlashNextSampleStartAddress); //getLicence()); write_label_var( 30, 800, ME_Y_LINE6, &FontT42, text); return UNSPECIFIC_RETURN; } +#endif uint8_t OnAction_SetBatteryCharge(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) {