Mercurial > public > ostc4
diff Discovery/Src/settings.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children | bf43851a678b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/settings.c Sat Apr 28 11:52:34 2018 +0200 @@ -0,0 +1,2851 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Src/settings.c +/// \brief settingsHelperButtonSens_translate_hwOS_values_to_percentage. +/// \author Heinrichs Weikamp gmbh +/// \date 6-March-2017 +/// +/// \details +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2018 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 <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// + +#include <string.h> +#include "settings.h" +#include "firmwareEraseProgram.h" // for HARDWAREDATA_ADDRESS +#include "externLogbookFlash.h" // for SAMPLESTART and SAMPLESTOP +#include "text_multilanguage.h" // for LANGUAGE_END +#include "tHome.h" // for CVIEW_END + +SSettings Settings; + +const uint8_t RTErequiredHigh = 1; +const uint8_t RTErequiredLow = 1; + +const uint8_t FONTrequiredHigh = 0; +const uint8_t FONTrequiredLow = 9; + +uint8_t RTEactualHigh = 0; +uint8_t RTEactualLow = 0; + +// =============================================================================== +// SFirmwareData FirmwareData +/// @brief internal counter is for changes after last release +/// use date and info as well for this purpose +/// +// =============================================================================== + +const SFirmwareData firmware_FirmwareData __attribute__( (section(".firmware_firmware_data")) ) = +{ + .versionFirst = 1, + .versionSecond = 3, + .versionThird = 2, + .versionBeta = 1, + + /* 4 bytes with trailing 0 */ + .signature = "cw", + + .release_year = 17, + .release_month = 7, + .release_day = 4, + .release_sub = 0, + + /* max 48 with trailing 0 */ + //release_info ="12345678901234567890123456789012345678901" + .release_info ="going on", + + /* for safety reasons and coming functions */ + .magic[0] = FIRMWARE_MAGIC_FIRST, + .magic[1] = FIRMWARE_MAGIC_SECOND, + .magic[2] = FIRMWARE_MAGIC_FIRMWARE, /* the magic byte */ + .magic[3] = FIRMWARE_MAGIC_END +}; + + +/* always adjust check_and_correct_settings() accordingly + * There might even be entries with fixed values that have no range + */ +const SSettings SettingsStandard = { + .header = 0xFFFF0017, + .warning_blink_dsec = 8 * 2, + .lastDiveLogId = 0, + .logFlashNextSampleStartAddress = 0, + + .gas[0].oxygen_percentage = 21, + .gas[1].oxygen_percentage = 21, + .gas[2].oxygen_percentage = 21, + .gas[3].oxygen_percentage = 21, + .gas[4].oxygen_percentage = 21, + .gas[5].oxygen_percentage = 21, + .gas[6].oxygen_percentage = 21, + .gas[7].oxygen_percentage = 21, + .gas[8].oxygen_percentage = 21, + .gas[9].oxygen_percentage = 21, + .gas[10].oxygen_percentage = 21, + .gas[0].helium_percentage = 0, + .gas[1].helium_percentage = 0, + .gas[2].helium_percentage = 0, + .gas[3].helium_percentage = 0, + .gas[4].helium_percentage = 0, + .gas[5].helium_percentage = 0, + .gas[6].helium_percentage = 0, + .gas[7].helium_percentage = 0, + .gas[8].helium_percentage = 0, + .gas[9].helium_percentage = 0, + .gas[10].helium_percentage = 0, + .gas[0].depth_meter = 0, + .gas[1].depth_meter = 0, + .gas[2].depth_meter = 0, + .gas[3].depth_meter = 0, + .gas[4].depth_meter = 0, + .gas[5].depth_meter = 0, + .gas[6].depth_meter = 0, + .gas[7].depth_meter = 0, + .gas[8].depth_meter = 0, + .gas[9].depth_meter = 0, + .gas[10].depth_meter = 0, + .gas[0].depth_meter_travel = 0, + .gas[1].depth_meter_travel = 0, + .gas[2].depth_meter_travel = 0, + .gas[3].depth_meter_travel = 0, + .gas[4].depth_meter_travel = 0, + .gas[5].depth_meter_travel = 0, + .gas[6].depth_meter_travel = 0, + .gas[7].depth_meter_travel = 0, + .gas[8].depth_meter_travel = 0, + .gas[9].depth_meter_travel = 0, + .gas[10].depth_meter_travel = 0, + .gas[0].note.uw = 0, + .gas[1].note.ub.first = 1, + .gas[1].note.ub.active = 1, + .gas[1].note.ub.deco = 0, + .gas[1].note.ub.travel = 0, + .gas[2].note.uw = 0, + .gas[3].note.uw = 0, + .gas[4].note.uw = 0, + .gas[5].note.uw = 0, + .gas[6].note.ub.first = 1, + .gas[6].note.ub.active = 1, + .gas[6].note.ub.deco = 0, + .gas[6].note.ub.travel = 0, + .gas[7].note.uw = 0, + .gas[8].note.uw = 0, + .gas[9].note.uw = 0, + .gas[10].note.uw = 0, + .gas[0].bottle_size_liter = 0, + .gas[1].bottle_size_liter = 0, + .gas[2].bottle_size_liter = 0, + .gas[3].bottle_size_liter = 0, + .gas[4].bottle_size_liter = 0, + .gas[5].bottle_size_liter = 0, + .gas[6].bottle_size_liter = 0, + .gas[7].bottle_size_liter = 0, + .gas[8].bottle_size_liter = 0, + .gas[9].bottle_size_liter = 0, + .gas[10].bottle_size_liter = 0, +/* + .gas[0].bottle_wireless_status = 0, + .gas[1].bottle_wireless_status = 0, + .gas[2].bottle_wireless_status = 0, + .gas[3].bottle_wireless_status = 0, + .gas[4].bottle_wireless_status = 0, + .gas[5].bottle_wireless_status = 0, + .gas[6].bottle_wireless_status = 0, + .gas[7].bottle_wireless_status = 0, + .gas[8].bottle_wireless_status = 0, + .gas[9].bottle_wireless_status = 0, + .gas[10].bottle_wireless_status = 0, +*/ + .gas[0].bottle_wireless_id = 0, + .gas[1].bottle_wireless_id = 0, + .gas[2].bottle_wireless_id = 0, + .gas[3].bottle_wireless_id = 0, + .gas[4].bottle_wireless_id = 0, + .gas[5].bottle_wireless_id = 0, + .gas[6].bottle_wireless_id = 0, + .gas[7].bottle_wireless_id = 0, + .gas[8].bottle_wireless_id = 0, + .gas[9].bottle_wireless_id = 0, + .gas[10].bottle_wireless_id = 0, + .setpoint[0].setpoint_cbar = 100, + .setpoint[1].setpoint_cbar = 70, + .setpoint[2].setpoint_cbar = 90, + .setpoint[3].setpoint_cbar = 100, + .setpoint[4].setpoint_cbar = 120, + .setpoint[5].setpoint_cbar = 140, + .setpoint[0].depth_meter = 0, + .setpoint[1].depth_meter = 0, + .setpoint[2].depth_meter = 0, + .setpoint[3].depth_meter = 0, + .setpoint[4].depth_meter = 0, + .setpoint[5].depth_meter = 0, + .setpoint[0].note.uw = 0, + .setpoint[1].note.ub.active = 1, + .setpoint[1].note.ub.first = 1, + .setpoint[2].note.ub.active = 1, + .setpoint[2].note.ub.first = 0, + .setpoint[3].note.ub.active = 1, + .setpoint[3].note.ub.first = 0, + .setpoint[4].note.ub.active = 1, + .setpoint[4].note.ub.first = 0, + .setpoint[5].note.ub.active = 1, + .setpoint[5].note.ub.first = 0, + + .CCR_Mode = CCRMODE_Sensors, + .dive_mode = DIVEMODE_OC, + .deco_type.ub.standard = GF_MODE, + .deco_type.ub.alternative = GF_MODE, + .ppO2_max_deco = 160, + .ppO2_max_std = 140, + .ppO2_min = 15, + .CNS_max = 90, + .ascent_MeterPerMinute_max = 30, + .ascent_MeterPerMinute_showGraph = 7, + .future_TTS = 5, + .GF_high = 85, + .GF_low = 30, + .aGF_high = 95, + .aGF_low = 95, + .VPM_conservatism.ub.standard = 2, + .VPM_conservatism.ub.alternative = 0, + .safetystopDuration = 1, + .AtemMinutenVolumenLiter = 25, + .ReserveFractionDenominator = 4, + .salinity = 0, + .last_stop_depth_meter = 3, + .stop_increment_depth_meter = 3, + .brightness = 1, + .date_format = DDMMYY, + .selected_language = 0, /* 0 = LANGUAGE_English */ + .customtext = " <your name>\n" " <address>", + .timeoutSurfacemode = 120, + .timeoutMenuSurface = 120,//240, + .timeoutMenuDive = 120,//20, + .timeoutMenuEdit = 120,//40, + .timeoutInfo = 120,//60, + .timeoutInfoCompass = 60, + .design = 7, + .timeoutDiveReachedZeroDepth = 300, + .divetimeToCreateLogbook = 60, + .serialHigh = 0, + .serialLow = 2, +/* + .firmwareVersion16to32bit.ub.first = 0, + .firmwareVersion16to32bit.ub.second = 6, + .firmwareVersion16to32bit.ub.third = 0, + .firmwareVersion16to32bit.ub.betaFlag = 0, +*/ + .backup_localtime_rtc_tr = 0, + .backup_localtime_rtc_dr = 0, + .totalDiveCounter = 0, + .personalDiveCount = 0, + .showDebugInfo = 0, + .ButtonResponsiveness[0] = 90, // new hw 170306 + .ButtonResponsiveness[1] = 90, // new hw 170306 + .ButtonResponsiveness[2] = 90, // new hw 170306 + .ButtonResponsiveness[3] = 90, // new hw 170306 + .nonMetricalSystem = 0, + .fallbackToFixedSetpoint = 1, + .bluetoothActive = 0, + .safetystopDepth = 5, + .updateSettingsAllowedFromHeader = 0xFFFF0002, + .scooterControl = 0, + .scooterDrag = 2, + .scooterLoad = 2, + .scooterNumberOfBatteries = 1, + .scooterBattSize = 760, + .scooterSPARE1[0] = 0, + .scooterSPARE2[0] = 0, + .ppo2sensors_deactivated = 0, + .tX_colorscheme = 0, + .tX_userselectedLeftLowerCornerPrimary = 1, + .tX_userselectedLeftLowerCornerTimeout = 0, + .tX_customViewPrimary = 1, + .tX_customViewTimeout = 0, + .timeoutEnterButtonSelectDive = 10, + .logbookOffset = 0, + .alwaysShowPPO2 = 0, + .extraDisplay = EXTRADISPLAY_BIGFONT, + .display_toogle_desc = 200, + .offsetPressure_mbar = 0, + .offsetTemperature_centigrad = 0, + .gasConsumption_travel_l_min = 30, + .gasConsumption_bottom_l_min = 30, + .gasConsumption_deco_l_min = 20, + .debugModeOnStart = 0, + .compassBearing = 0, + .lastKnownBatteryPercentage = 0, + .buttonBalance[0] = 3, + .buttonBalance[1] = 3, + .buttonBalance[2] = 3, + .firmwareVersion[0] = 0,//FirmwareData.firmwareVersion16to32bit.ub.first, + .firmwareVersion[1] = 0,//FirmwareData.firmwareVersion16to32bit.ub.second, + .firmwareVersion[2] = 0,//FirmwareData.firmwareVersion16to32bit.ub.third, + .firmwareVersion[3] = 0,//FirmwareData.firmwareVersion16to32bit.ub.betaFlag, + .timeoutSurfacemodeWithSensors = 600, + .VPM_model = 0, + .GF_model = 0, + .FactoryButtonBase = 90, + .FactoryButtonBalance[0] = 3, + .FactoryButtonBalance[1] = 3, + .FactoryButtonBalance[2] = 3, +}; + +/* Private function prototypes -----------------------------------------------*/ +uint8_t checkValue(uint8_t value,uint8_t from, uint8_t to); + +/* Functions -----------------------------------------------------------------*/ + + +// =============================================================================== +// set_new_settings_missing_in_ext_flash +/// @brief Add all the new setting variables of this version +/// or/and change what has changed in the meantime +/// +/// Additionally update the serial number if written via bluetooth +/// +// =============================================================================== +void set_new_settings_missing_in_ext_flash(void) +{ + // never delete this part setting the serial + if(hardwareDataGetPointer()->secondarySerial != 0xFFFF) + { + settingsGetPointer()->serialHigh = (hardwareDataGetPointer()->secondarySerial / 256); + settingsGetPointer()->serialLow = (hardwareDataGetPointer()->secondarySerial & 0xFF); + } + else + if(hardwareDataGetPointer()->primarySerial != 0xFFFF) + { + settingsGetPointer()->serialHigh = (hardwareDataGetPointer()->primarySerial / 256); + settingsGetPointer()->serialLow = (hardwareDataGetPointer()->primarySerial & 0xFF); + } + else + { + settingsGetPointer()->serialHigh = 0; + settingsGetPointer()->serialLow = 0; + } + + settingsGetPointer()->firmwareVersion[0] = firmware_FirmwareData.versionFirst; + settingsGetPointer()->firmwareVersion[1] = firmware_FirmwareData.versionSecond; + settingsGetPointer()->firmwareVersion[2] = firmware_FirmwareData.versionThird; + settingsGetPointer()->firmwareVersion[3] = firmware_FirmwareData.versionBeta; + + SSettings* pSettings = settingsGetPointer(); + const SSettings* pStandard = settingsGetPointerStandard(); + + pSettings->scooterControl = 0; + + if((pSettings->serialHigh == 0) && (pSettings->serialLow == 25)) + { + memcpy(pSettings->customtext, " Salom�\n\r" " Wiedmer\n\r", 60); + } + + switch(pSettings->header) + { + case 0xFFFF0000: + case 0xFFFF0001: + case 0xFFFF0002: + case 0xFFFF0003: + case 0xFFFF0004: + case 0xFFFF0005: + pSettings->ppo2sensors_deactivated = pStandard->ppo2sensors_deactivated; + pSettings->tX_colorscheme = pStandard->tX_colorscheme; + pSettings->tX_userselectedLeftLowerCornerPrimary = pStandard->tX_userselectedLeftLowerCornerPrimary; + pSettings->tX_userselectedLeftLowerCornerTimeout = pStandard->tX_userselectedLeftLowerCornerTimeout; + pSettings->tX_customViewPrimary = pStandard->tX_customViewPrimary; + pSettings->tX_customViewTimeout = pStandard->tX_customViewTimeout; + // no break + case 0xFFFF0006: + pSettings->timeoutEnterButtonSelectDive = pStandard->timeoutEnterButtonSelectDive; + pSettings->ButtonResponsiveness[0] = pStandard->ButtonResponsiveness[0]; + pSettings->ButtonResponsiveness[1] = pStandard->ButtonResponsiveness[1]; + pSettings->ButtonResponsiveness[2] = pStandard->ButtonResponsiveness[2]; + pSettings->ButtonResponsiveness[3] = pStandard->ButtonResponsiveness[3]; + pSettings->timeoutSurfacemode = pStandard->timeoutSurfacemode; + pSettings->timeoutMenuSurface = pStandard->timeoutMenuSurface; + pSettings->timeoutMenuDive = pStandard->timeoutMenuDive; + pSettings->timeoutMenuEdit = pStandard->timeoutMenuEdit; + pSettings->timeoutInfo = pStandard->timeoutInfo; + pSettings->timeoutInfoCompass = pStandard->timeoutInfoCompass; + pSettings->timeoutDiveReachedZeroDepth = pStandard->timeoutDiveReachedZeroDepth; + pSettings->divetimeToCreateLogbook = pStandard->divetimeToCreateLogbook; + pSettings->safetystopDuration = pStandard->safetystopDuration; // change from on/off to minutes + // no break + case 0xFFFF0007: + case 0xFFFF0008: + pSettings->alwaysShowPPO2 = pStandard->alwaysShowPPO2; + pSettings->logbookOffset = pStandard->logbookOffset; + // no break + case 0xFFFF0009: + pSettings->extraDisplay = pStandard->extraDisplay; + // no break + case 0xFFFF000A: + pSettings->display_toogle_desc = pStandard->display_toogle_desc; + // no break + case 0xFFFF000B: + pSettings->offsetPressure_mbar = pStandard->offsetPressure_mbar; + pSettings->offsetTemperature_centigrad = pStandard->offsetTemperature_centigrad; + pSettings->gasConsumption_travel_l_min = pStandard->gasConsumption_travel_l_min; + pSettings->gasConsumption_bottom_l_min = pStandard->gasConsumption_bottom_l_min; + pSettings->gasConsumption_deco_l_min = pStandard->gasConsumption_deco_l_min; + // no break + case 0xFFFF000C: + memcpy(pSettings->customtext, " hwOS 4\n\r" " welcome\n\r", 60); + // no break + case 0xFFFF000D: // nothing to do from 0xFFFF000D to 0xFFFF000E, just about header :-) + case 0xFFFF000E: + pSettings->debugModeOnStart = 0; + // no break + case 0xFFFF000F: + pSettings->compassBearing = 0; + // no break + case 0xFFFF0010: + pSettings->scooterDrag = 2; + pSettings->scooterLoad = 2; + pSettings->scooterSPARE1[0] = 0; + pSettings->scooterSPARE2[0] = 0; + // no break + case 0xFFFF0011: + pSettings->scooterNumberOfBatteries = 1; + pSettings->scooterBattSize = 760; + pSettings->lastKnownBatteryPercentage = 0; + // no break + case 0xFFFF0012: + pSettings->buttonBalance[0] = 3; + pSettings->buttonBalance[1] = 3; + pSettings->buttonBalance[2] = 3; + // no break + case 0xFFFF0013: + case 0xFFFF0014: + pSettings->timeoutSurfacemodeWithSensors = pStandard->timeoutSurfacemodeWithSensors; + // no break + case 0xFFFF0015: + pSettings->ButtonResponsiveness[3] = pStandard->ButtonResponsiveness[3]; + settingsHelperButtonSens_keepPercentageValues(settingsHelperButtonSens_translate_hwOS_values_to_percentage(pSettings->ButtonResponsiveness[3]), pSettings->ButtonResponsiveness); + pSettings->VPM_model = 0; + pSettings->GF_model = 0; + // no break + case 0xFFFF0016: + pSettings->FactoryButtonBase = pStandard->FactoryButtonBase; + pSettings->FactoryButtonBalance[0] = pStandard->FactoryButtonBalance[0]; + pSettings->FactoryButtonBalance[1] = pStandard->FactoryButtonBalance[1]; + pSettings->FactoryButtonBalance[2] = pStandard->FactoryButtonBalance[2]; + // no break + default: + pSettings->header = pStandard->header; + break; // no break before!! + } +} + + +uint8_t newFirmwareVersionCheckViaSettings(void) +{ + SSettings* pSettings = settingsGetPointer(); + + if(pSettings->header < 0xFFFF0014) // for the versions without firmwareVersion[] + return 1; + + if(pSettings->firmwareVersion[0] != firmware_FirmwareData.versionFirst) + return 1; + if(pSettings->firmwareVersion[1] != firmware_FirmwareData.versionSecond) + return 1; + if(pSettings->firmwareVersion[2] != firmware_FirmwareData.versionThird) + return 1; + if(pSettings->firmwareVersion[3] != firmware_FirmwareData.versionBeta) + return 1; + + return 0; +} + + +void set_settings_button_to_standard_with_individual_buttonBalance(void) +{ + settingsHelperButtonSens_keepPercentageValues(SettingsStandard.ButtonResponsiveness[3], settingsGetPointer()->ButtonResponsiveness); +} + + +uint8_t check_and_correct_settings(void) +{ + uint32_t corrections = 0; + uint8_t firstGasFoundOC = 0; + uint8_t firstGasFoundCCR = 0; + +/* uint32_t header; + */ + +/* uint8_t warning_blink_dsec; 1/10 seconds + */ + if((Settings.warning_blink_dsec < 1) || (Settings.warning_blink_dsec > 100)) + { + Settings.warning_blink_dsec = SettingsStandard.warning_blink_dsec; + corrections++; + } + +/* uint8_t lastDiveLogId; + */ + +/* uint32_t logFlashNextSampleStartAddress; + */ + if((Settings.logFlashNextSampleStartAddress < SAMPLESTART) || (Settings.logFlashNextSampleStartAddress > SAMPLESTOP)) + { + Settings.logFlashNextSampleStartAddress = SAMPLESTART; + corrections++; + } + + +/* uint8_t dive_mode; has to before the gases + */ + if( (Settings.dive_mode != DIVEMODE_OC) && + (Settings.dive_mode != DIVEMODE_CCR) && + (Settings.dive_mode != DIVEMODE_Gauge) && + (Settings.dive_mode != DIVEMODE_Apnea) ) + { + Settings.dive_mode = DIVEMODE_OC; + corrections++; + } + + +/* SGasLine gas[1 + (2*NUM_GASES)]; + */ + for(int i=1; i<=2*NUM_GASES;i++) + { + if(Settings.gas[i].oxygen_percentage < 4) + { + Settings.gas[i].oxygen_percentage = 4; + corrections++; + } + if(Settings.gas[i].oxygen_percentage > 100) + { + Settings.gas[i].oxygen_percentage = 100; + corrections++; + } + if((Settings.gas[i].oxygen_percentage + Settings.gas[i].helium_percentage) > 100) + { + Settings.gas[i].helium_percentage = 100 - Settings.gas[i].oxygen_percentage; + corrections++; + } + if(Settings.gas[i].note.ub.deco) + { + if(Settings.gas[i].note.ub.active != 1) + { + Settings.gas[i].note.ub.active = 1; + corrections++; + } + if(Settings.gas[i].note.ub.travel == 1) + { + Settings.gas[i].note.ub.travel = 0; + corrections++; + } + } + if(Settings.gas[i].note.ub.travel) + { + if(Settings.gas[i].note.ub.active != 1) + { + Settings.gas[i].note.ub.active = 1; + corrections++; + } + if(Settings.gas[i].note.ub.deco == 1) + { + Settings.gas[i].note.ub.deco = 0; + corrections++; + } + } + if(Settings.gas[i].note.ub.first) + { + if(Settings.setpoint[i].note.ub.active != 1) + { + Settings.setpoint[i].note.ub.active = 1; + corrections++; + } + if(Settings.gas[i].note.ub.travel == 1) + { + Settings.gas[i].note.ub.travel = 0; + corrections++; + } + if(Settings.gas[i].note.ub.deco == 1) + { + Settings.gas[i].note.ub.deco = 0; + corrections++; + } + if((i<=NUM_GASES) && (!firstGasFoundOC)) + firstGasFoundOC = 1; + else + if((i>NUM_GASES) && (!firstGasFoundCCR)) + firstGasFoundCCR = 1; + else + Settings.gas[i].note.ub.first = 0; + } + if(Settings.gas[i].bottle_size_liter > 40) + { + Settings.gas[i].bottle_size_liter = 40; + corrections++; + } + if(Settings.gas[i].depth_meter > 250) + { + Settings.gas[i].depth_meter = 250; + corrections++; + } + if(Settings.gas[i].depth_meter_travel > 250) + { + Settings.gas[i].depth_meter_travel = 250; + corrections++; + } + /*if(Settings.gas[i].note.ub.senderCode) + { + } + if(Settings.gas[i].bottle_wireless_id) + { + } + */ + } // for(int i=1; i<=2*NUM_GASES;i++) + + if(!firstGasFoundOC) + { + Settings.gas[1].note.ub.active = 1; + Settings.gas[1].note.ub.first = 1; + Settings.gas[1].note.ub.travel = 0; + Settings.gas[1].note.ub.deco = 0; + } + if(!firstGasFoundCCR) + { + Settings.gas[1 + NUM_GASES].note.ub.active = 1; + Settings.gas[1 + NUM_GASES].note.ub.first = 1; + Settings.gas[1 + NUM_GASES].note.ub.travel = 0; + Settings.gas[1 + NUM_GASES].note.ub.deco = 0; + } +/* SSetpointLine setpoint[1 + NUM_GASES]; + */ + for(int i=1; i<=NUM_GASES;i++) + { + if(Settings.setpoint[i].setpoint_cbar < 50) + { + Settings.setpoint[i].setpoint_cbar = 50; + corrections++; + } + if(Settings.setpoint[i].setpoint_cbar > 160) + { + Settings.setpoint[i].setpoint_cbar = 160; + corrections++; + } + if(Settings.setpoint[i].depth_meter > 250) + { + Settings.setpoint[i].depth_meter = 250; + corrections++; + } + if(Settings.setpoint[i].note.ub.deco) + { + if(Settings.setpoint[i].note.ub.active != 1) + { + Settings.setpoint[i].note.ub.active = 1; + corrections++; + } + if(Settings.setpoint[i].note.ub.travel == 1) + { + Settings.setpoint[i].note.ub.travel = 0; + corrections++; + } + } + if(Settings.setpoint[i].note.ub.travel) + { + if(Settings.setpoint[i].note.ub.active != 1) + { + Settings.setpoint[i].note.ub.active = 1; + corrections++; + } + if(Settings.setpoint[i].note.ub.deco == 1) + { + Settings.setpoint[i].note.ub.deco = 0; + corrections++; + } + } + if(Settings.setpoint[i].note.ub.first) + { + if(Settings.setpoint[i].note.ub.active != 1) + { + Settings.setpoint[i].note.ub.active = 1; + corrections++; + } + if(Settings.setpoint[i].note.ub.travel == 1) + { + Settings.setpoint[i].note.ub.travel = 0; + corrections++; + } + if(Settings.setpoint[i].note.ub.deco == 1) + { + Settings.setpoint[i].note.ub.deco = 0; + corrections++; + } + } + } // for(int i=1; i<=NUM_GASES;i++) + +/* uint8_t CCR_Mode; + */ + if( (Settings.CCR_Mode != CCRMODE_Sensors) && + (Settings.CCR_Mode != CCRMODE_FixedSetpoint)) + { + Settings.CCR_Mode = CCRMODE_FixedSetpoint; + corrections++; + } + +/* split2x4_Type deco_type; + */ + if( (Settings.deco_type.ub.standard != GF_MODE) && + (Settings.deco_type.ub.standard != VPM_MODE)) + { + Settings.deco_type.ub.standard = VPM_MODE; + corrections++; + } + if(Settings.deco_type.ub.alternative != GF_MODE) + { + Settings.deco_type.ub.alternative = GF_MODE; + corrections++; + } + +/* uint8_t ppO2_max_deco; + */ + if(Settings.ppO2_max_deco > 190) + { + Settings.ppO2_max_deco = 190; + corrections++; + } + if(Settings.ppO2_max_deco < 100) + { + Settings.ppO2_max_deco = 100; + corrections++; + } + +/* uint8_t ppO2_max_std; + */ + if(Settings.ppO2_max_std > 190) + { + Settings.ppO2_max_std = 190; + corrections++; + } + if(Settings.ppO2_max_std < 100) + { + Settings.ppO2_max_std = 100; + corrections++; + } + +/* uint8_t ppO2_min; + */ + if(Settings.ppO2_min != 15) + { + Settings.ppO2_min = 15; + corrections++; + } + +/* uint8_t CNS_max; + */ + if(Settings.CNS_max != 90) + { + Settings.CNS_max = 90; + corrections++; + } + +/* uint8_t ascent_MeterPerMinute_max; + */ + if(Settings.ascent_MeterPerMinute_max != 30) + { + Settings.ascent_MeterPerMinute_max = 30; + corrections++; + } + +/* uint8_t ascent_MeterPerMinute_showGraph; + */ + if(Settings.ascent_MeterPerMinute_showGraph != 30) + { + Settings.ascent_MeterPerMinute_showGraph = 30; + corrections++; + } + +/* uint8_t future_TTS; + */ + if(Settings.future_TTS > 15) + { + Settings.future_TTS = 15; + corrections++; + } + +/* uint8_t GF_high; + */ + if(Settings.GF_high > 99) + { + Settings.GF_high = 99; + corrections++; + } + if(Settings.GF_high < 45) + { + Settings.GF_high = 45; + corrections++; + } + +/* uint8_t GF_low; + */ + if(Settings.GF_low > 99) + { + Settings.GF_low = 99; + corrections++; + } + if(Settings.GF_low < 10) + { + Settings.GF_low = 10; + corrections++; + } + if(Settings.GF_low > Settings.GF_high) + { + Settings.GF_low = Settings.GF_high; + corrections++; + } + +/* uint8_t aGF_high; + */ + if(Settings.aGF_high > 99) + { + Settings.aGF_high = 99; + corrections++; + } + if(Settings.aGF_high < 45) + { + Settings.aGF_high = 45; + corrections++; + } + +/* uint8_t aGF_low; + */ + if(Settings.aGF_low > 99) + { + Settings.aGF_low = 99; + corrections++; + } + if(Settings.aGF_low < 10) + { + Settings.aGF_low = 10; + corrections++; + } + if(Settings.aGF_low > Settings.aGF_high) + { + Settings.aGF_low = Settings.aGF_high; + corrections++; + } + +/* split2x4_Type VPM_conservatism; + */ + if(Settings.VPM_conservatism.ub.standard > 5) + { + Settings.VPM_conservatism.ub.standard = 5; + corrections++; + } + if(Settings.VPM_conservatism.ub.alternative > 5) + { + Settings.VPM_conservatism.ub.alternative = 5; + corrections++; + } + +/* uint8_t safetystopDuration; + */ + if(Settings.safetystopDuration > 5) + { + Settings.safetystopDuration = 5; + corrections++; + } + +/* uint8_t AtemMinutenVolumenLiter; + */ + if(Settings.AtemMinutenVolumenLiter != 25) + { + Settings.AtemMinutenVolumenLiter = 25; + corrections++; + } + +/* uint8_t ReserveFractionDenominator; + */ + if(Settings.ReserveFractionDenominator != 4) + { + Settings.ReserveFractionDenominator = 4; + corrections++; + } + +/* uint8_t salinity; + */ + if(Settings.salinity > 4) + { + Settings.salinity = 4; + corrections++; + } + +/* uint8_t last_stop_depth_meter; + */ + if(Settings.last_stop_depth_meter > 9) + { + Settings.last_stop_depth_meter = 9; + corrections++; + } + if(Settings.last_stop_depth_meter < 3) + { + Settings.last_stop_depth_meter = 3; + corrections++; + } + +/* uint8_t stop_increment_depth_meter; + */ + if(Settings.stop_increment_depth_meter != 3) + { + Settings.stop_increment_depth_meter = 3; + corrections++; + } + +/* uint8_t brightness; + */ + if(Settings.brightness > 4) + { + Settings.brightness = 4; + corrections++; + } + +/* uint8_t date_format; + */ + if( (Settings.date_format != DDMMYY) && + (Settings.date_format != MMDDYY) && + (Settings.date_format != YYMMDD)) + { + Settings.date_format = DDMMYY; + corrections++; + } + +/* uint8_t selected_language; + */ + if(Settings.selected_language >= LANGUAGE_END) + { + Settings.selected_language = LANGUAGE_English; + corrections++; + } + +/* char customtext[60]; + */ + if(Settings.customtext[59] != 0) + { + Settings.customtext[59] = 0; + corrections++; + } + +/* uint16_t timeoutSurfacemode; + */ + if( (Settings.timeoutSurfacemode != 20) && // Quick Sleep Option + (Settings.timeoutSurfacemode != 120)) + { + Settings.timeoutSurfacemode = 120; + corrections++; + } + +/* uint8_t timeoutMenuSurface; + */ + if(Settings.timeoutMenuSurface != 120) + { + Settings.timeoutMenuSurface = 120; + corrections++; + } + +/* uint8_t timeoutMenuDive; + */ + if(Settings.timeoutMenuDive != 120) + { + Settings.timeoutMenuDive = 120; + corrections++; + } + +/* uint8_t timeoutMenuEdit; + */ + if(Settings.timeoutMenuEdit != 120) + { + Settings.timeoutMenuEdit = 120; + corrections++; + } + +/* uint8_t timeoutInfo; + */ + if(Settings.timeoutInfo != 120) + { + Settings.timeoutInfo = 120; + corrections++; + } + +/* uint8_t timeoutInfoCompass; + */ + if(Settings.timeoutInfoCompass != 60) + { + Settings.timeoutInfoCompass = 60; + corrections++; + } + +/* uint8_t design; + */ + if(Settings.design != 7) + { + Settings.design = 7; + corrections++; + } + +/* uint16_t timeoutDiveReachedZeroDepth; + */ + if(Settings.timeoutDiveReachedZeroDepth != 300) + { + Settings.timeoutDiveReachedZeroDepth = 300; + corrections++; + } + +/* uint16_t divetimeToCreateLogbook; + */ + if(Settings.divetimeToCreateLogbook != 60) + { + Settings.divetimeToCreateLogbook = 60; + corrections++; + } + +/* uint8_t serialHigh; + */ + +/* uint8_t serialLow; + */ + +/* SUFirmware firmwareVersion16to32bit; + */ + +/* uint32_t backup_localtime_rtc_tr; + */ + +/* uint32_t backup_localtime_rtc_dr; + */ + +/* uint16_t totalDiveCounter; + */ + +/* uint16_t personalDiveCount; + */ + +/* uint8_t showDebugInfo; + */ + if(Settings.showDebugInfo > 1) + { + Settings.showDebugInfo = 0; + corrections++; + } + +/* uint8_t ButtonResponsiveness[4]; + */ + // Base value, index 3 + if(Settings.ButtonResponsiveness[3] < 70) + { + Settings.ButtonResponsiveness[3] = 70; + corrections++; + } + else + if(Settings.ButtonResponsiveness[3] > 110) + { + Settings.ButtonResponsiveness[3] = 130; + corrections++; + } + // flex values 0, 1, 2 + for(int i=0; i<3;i++) + { + if(Settings.ButtonResponsiveness[i] < 60) // 70-10 + { + Settings.ButtonResponsiveness[i] = 70; + corrections++; + } + else + if(Settings.ButtonResponsiveness[i] > 130) // 110+20 + { + Settings.ButtonResponsiveness[i] = 130; + corrections++; + } + } + +/* uint8_t buttonBalance[3]; + */ + for(int i=0; i<3;i++) + { + if(Settings.buttonBalance[i] < 2) // 2 = -10 + { + Settings.buttonBalance[i] = 2; + corrections++; + } + else + if(Settings.buttonBalance[i] > 5) // 3 = 0, 4 = +10, 5 = +20 + { + Settings.buttonBalance[i] = 5; + corrections++; + } + } + +/* uint8_t nonMetricalSystem; + */ + if(Settings.nonMetricalSystem > 1) + { + Settings.nonMetricalSystem = 1; + corrections++; + } + +/* uint8_t fallbackToFixedSetpoint; + */ + if(Settings.fallbackToFixedSetpoint > 1) + { + Settings.fallbackToFixedSetpoint = 1; + corrections++; + } + +/* uint8_t bluetoothActive; + */ + if(Settings.bluetoothActive > 1) + { + Settings.bluetoothActive = 1; + corrections++; + } + +/* uint8_t safetystopDepth; + */ + if(Settings.safetystopDepth > 6) + { + Settings.safetystopDepth = 6; + corrections++; + } + if(Settings.safetystopDepth < 3) + { + Settings.safetystopDepth = 3; + corrections++; + } + +/* uint32_t updateSettingsAllowedFromHeader; + */ + +/* uint8_t scooterControl; + */ + if(Settings.scooterControl > 1) + { + Settings.scooterControl = 1; + corrections++; + } + +/* char scooterDeviceAddress[12]; + */ + +/* char scooterDeviceName[19]; +*/ + +/* uint8_t ppo2sensors_deactivated; + */ + if(Settings.ppo2sensors_deactivated > (1+2+4)) + { + Settings.ppo2sensors_deactivated = 0; + corrections++; + } + +/* uint8_t tX_colorscheme; + */ + if(Settings.tX_colorscheme > 3) + { + Settings.tX_colorscheme = 0; + corrections++; + } + +/* uint8_t tX_userselectedLeftLowerCornerPrimary; + */ + if(Settings.tX_userselectedLeftLowerCornerPrimary > 7) + { + Settings.tX_userselectedLeftLowerCornerPrimary = 1; + corrections++; + } + +/* uint8_t tX_userselectedLeftLowerCornerTimeout; + */ + if(Settings.tX_userselectedLeftLowerCornerTimeout > 60) + { + Settings.tX_userselectedLeftLowerCornerTimeout = 0; + corrections++; + } + +/* uint8_t tX_customViewPrimary; + */ + if(Settings.tX_customViewPrimary >= CVIEW_END) + { + Settings.tX_customViewPrimary = 1; + corrections++; + } + +/* uint8_t tX_customViewTimeout; + */ + if(Settings.tX_customViewTimeout > 60) + { + Settings.tX_customViewTimeout = 0; + corrections++; + } + +/* uint8_t timeoutEnterButtonSelectDive; + */ + if(Settings.timeoutEnterButtonSelectDive != 10) + { + Settings.timeoutEnterButtonSelectDive = 10; + corrections++; + } + +/* uint8_t logbookOffset; + */ + if(Settings.logbookOffset > 9000) + { + Settings.logbookOffset = 0; + corrections++; + } + +/* uint8_t alwaysShowPPO2; + */ + if(Settings.alwaysShowPPO2 > 1) + { + Settings.alwaysShowPPO2 = 0; + corrections++; + } + +/* uint8_t extraDisplay; + */ + if(Settings.extraDisplay >= EXTRADISPLAY_END) + { + Settings.extraDisplay = EXTRADISPLAY_BIGFONT; + corrections++; + } + +/* int8_t offsetPressure_mbar; + */ + if((Settings.offsetPressure_mbar > 20) || + (Settings.offsetPressure_mbar < -20)) + { + Settings.offsetPressure_mbar = 0; + corrections++; + } + +/* int8_t offsetTemperature_centigrad; + */ + if((Settings.offsetTemperature_centigrad > 20) || + (Settings.offsetTemperature_centigrad < -20)) + { + Settings.offsetTemperature_centigrad = 0; + corrections++; + } + +/* uint8_t gasConsumption_travel_l_min; + */ + if((Settings.gasConsumption_travel_l_min < 5) || + (Settings.gasConsumption_travel_l_min > 50)) + { + Settings.gasConsumption_travel_l_min = 20; + corrections++; + } + +/* uint8_t gasConsumption_bottom_l_min; + */ + if((Settings.gasConsumption_bottom_l_min < 5) || + (Settings.gasConsumption_bottom_l_min > 50)) + { + Settings.gasConsumption_bottom_l_min = 20; + corrections++; + } + +/* uint8_t gasConsumption_deco_l_min; + */ + if((Settings.gasConsumption_deco_l_min < 5) || + (Settings.gasConsumption_deco_l_min > 50)) + { + Settings.gasConsumption_deco_l_min = 20; + corrections++; + } + +/* uint8_t showDebugInfo; + */ +#ifdef BOOT16 + Settings.showDebugInfo = 0; +#else + if(Settings.showDebugInfo > 1) + Settings.showDebugInfo = 0; + +#endif + +/* uint8_t selected_language; + */ +#ifdef BOOT16 + if(Settings.selected_language > 1) + Settings.selected_language = 0; +#else + if(Settings.selected_language > 4) + Settings.selected_language = 0; +#endif + + +/* uint8_t display_toogle_desc; 1/10 seconds + */ + if((Settings.display_toogle_desc < 20) || (Settings.display_toogle_desc > 600)) + { + Settings.display_toogle_desc = SettingsStandard.display_toogle_desc; + corrections++; + } + +/* uint8_t debugModeOnStart; + */ + if(Settings.debugModeOnStart > 1) + { + Settings.debugModeOnStart = 0; + corrections++; + } + + +/* uint8_t IAmStolenPleaseKillMe; + */ + + if(hardwareDataGetPointer()->primarySerial == 90) + Settings.IAmStolenPleaseKillMe++; + else + Settings.IAmStolenPleaseKillMe = 0; + + +/* uint8_t debugModeOnStart; + */ + if(Settings.compassBearing > 360) + { + Settings.compassBearing = 0; + corrections++; + } + +/* uint8_t scooterDrag; + */ + if(Settings.scooterDrag > 3) + { + Settings.scooterDrag = 3; + corrections++; + } + +/* uint8_t scooterLoad; + */ + if(Settings.scooterLoad > 4) + { + Settings.scooterLoad = 4; + corrections++; + } + +/* uint8_t scooterNumberOfBatteries; + */ + if(Settings.scooterNumberOfBatteries > 3) + { + Settings.scooterNumberOfBatteries = 3; + corrections++; + } + +/* uint16_t scooterBattSize; + */ + if((Settings.scooterBattSize < 300) || + (Settings.scooterBattSize > 5000)) + { + Settings.scooterBattSize = 700; + corrections++; + } + + +/* uint8_t lastKnownBatteryPercentage; + */ + if(Settings.lastKnownBatteryPercentage > 100) + { + Settings.lastKnownBatteryPercentage = 100; + corrections++; + } + +/* uint8_t VPM_model + */ + if((Settings.VPM_model != VPM_FROM_FORTRAN) && (Settings.VPM_model != VPM_BACHELORWORK)) + { + Settings.VPM_model = VPM_FROM_FORTRAN; + corrections++; + } + +/* uint8_t Buehlmann_model + */ + if((Settings.GF_model != BUEHLMANN_OSTC4) && (Settings.GF_model != BUEHLMANN_hwOS)) + { + Settings.GF_model = BUEHLMANN_OSTC4; + corrections++; + } + + + if(corrections > 255) + return 255; + else + return (uint8_t)corrections; +} + + +/* always at 0x8080000, do not move -> bootloader access */ +const SFirmwareData* firmwareDataGetPointer(void) +{ + return &firmware_FirmwareData; +} + + +#ifndef SPECIALPROGRAMM +const SHardwareData* hardwareDataGetPointer(void) +{ + return (SHardwareData *)HARDWAREDATA_ADDRESS; +} +#endif + +const SSettings* settingsGetPointerStandard(void) +{ + return &SettingsStandard; +} + + +void hardwareBatchCode(uint8_t *high, uint8_t *low) +{ + if(high) + { + *high = (uint8_t)((hardwareDataGetPointer()->production_year - 16) * 16); + *high += hardwareDataGetPointer()->production_month; + if(low) + { + *low = (uint8_t)(hardwareDataGetPointer()->production_day * 8); + } + } +} + + +uint8_t firmwareVersion_16bit_high(void) +{ + return ((firmware_FirmwareData.versionFirst & 0x1F) << 3) + ((firmware_FirmwareData.versionSecond & 0x1C) >> 5); +} + +uint8_t firmwareVersion_16bit_low(void) +{ + return ((firmware_FirmwareData.versionSecond & 0x03) << 6) + ((firmware_FirmwareData.versionThird & 0x1F) << 1) + (firmware_FirmwareData.versionBeta & 0x01); +} + +SSettings* settingsGetPointer(void) +{ + return &Settings; +} + + +// =============================================================================== +// set_settings_to_Standard +/// @brief This function overwrites the current settings of the system +/// with the EXCEPTION of the personalDiveCount +/// +/// It additionally calls set_new_settings_missing_in_ext_flash() and +/// check_and_correct_settings(), even so this shouldn't be necessary. +/// It is called on every start and from Reset All. +/// +/// 160622 added lastDiveLogIdBackup +/// +// =============================================================================== +void set_settings_to_Standard(void) +{ + SSettings *pSettings; + const SSettings *pSettingsStandard; + uint16_t personalDiveCountBackup; + uint8_t lastDiveLogIdBackup; + pSettings = settingsGetPointer(); + pSettingsStandard = settingsGetPointerStandard(); + + personalDiveCountBackup = pSettings->personalDiveCount; + lastDiveLogIdBackup = pSettings->lastDiveLogId; + memcpy(pSettings,pSettingsStandard,sizeof(*pSettings)); + pSettings->personalDiveCount = personalDiveCountBackup; + pSettings->lastDiveLogId = lastDiveLogIdBackup; + + pSettings->firmwareVersion[0] = firmware_FirmwareData.versionFirst; + pSettings->firmwareVersion[1] = firmware_FirmwareData.versionSecond; + pSettings->firmwareVersion[2] = firmware_FirmwareData.versionThird; + pSettings->firmwareVersion[3] = firmware_FirmwareData.versionBeta; + + set_new_settings_missing_in_ext_flash(); + check_and_correct_settings(); + // has to be called too: createDiveSettings(); +} + + +// =============================================================================== +// mod_settings_for_first_start_with_empty_ext_flash +/// @brief This function overwrites some settings of the system +/// It is called on every start. +/// Those settings will be overwriten by ext_flash_read_settings() +/// Will be kept if ext_flash_read_settings() is invalid because +/// it is still empty. +/// +// =============================================================================== +void mod_settings_for_first_start_with_empty_ext_flash(void) +{ + settingsGetPointer()->debugModeOnStart = 1; // +} + + + +// =============================================================================== +// hwOS4_to_hwOS_GasType +/// @brief Helper for get gas / diluent +/// +// =============================================================================== +uint8_t hwOS4_to_hwOS_GasType(uint8_t inOSTC4style) +{ + switch(inOSTC4style) + { + case (1+2): // first + case (2): // first + return 1; // hwOS style first + case (1+4): // deco + case (4): // deco + return 3; // hwOS style deco + case (1+8): // travel + case (8): // travel + return 2; // hwOS style travel + default: + return 0; // hwOS style Disabled + } +} + + +// =============================================================================== +// hwOS_to_hwOS4_GasType +/// @brief Helper for set gas / diluent +/// +// =============================================================================== +uint8_t hwOS_to_hwOS4_GasType(uint8_t inOSTC4style) +{ + switch(inOSTC4style) + { + case (1): // first + return 1+2; // hwOS4 style first + case (2): // travel (normal for diluent) + return 1+8; // hwOS4 style travel + case (3): // deco + return 1+4; // hwOS4 style deco + default: + return 0; // hwOS4 style inactive + } +} + + + +// =============================================================================== +// setGas +/// @brief This function overwrites one gas, including mode and deco depth, +/// it returns 0x4D prompt which is not used by writeData() that calls it. +/// +/// @param i the gas id from 1 to 5 for OC and 6 to 10 for CCR, 0 is the extra gas +/// @param *data 5 bytes with the first the command to call setGas and the four +/// following bytes to define oxygen, helium, mode and deco depth +/// +/// @return 0x4D (prompt that is not used) +// =============================================================================== +uint8_t setGas(int i,uint8_t * data) +{ + if(!checkValue(data[1],4,100)) + return ERROR_; + if(!checkValue(data[4],0,250)) + return ERROR_; + + Settings.gas[i].oxygen_percentage = data[1]; + Settings.gas[i].helium_percentage = data[2]; + Settings.gas[i].note.uw = hwOS_to_hwOS4_GasType(data[3]); + Settings.gas[i].depth_meter = data[4]; + return 0x4d; +} + + +uint8_t getGas(int i,uint8_t * data) +{ + data[0] = Settings.gas[i].oxygen_percentage; + data[1] = Settings.gas[i].helium_percentage; + data[2] = hwOS4_to_hwOS_GasType(Settings.gas[i].note.uw); + data[3] = Settings.gas[i].depth_meter; + return 0x4d; +} + +uint8_t setDiluent(int i,uint8_t * data) +{ + if(!checkValue(data[1],4,100)) + return ERROR_; + if(!checkValue(data[4],0,250)) + return ERROR_; + + Settings.gas[NUM_OFFSET_DILUENT + i].oxygen_percentage = data[1]; + Settings.gas[NUM_OFFSET_DILUENT + i].helium_percentage = data[2]; + Settings.gas[NUM_OFFSET_DILUENT + i].note.uw = hwOS_to_hwOS4_GasType(data[3]); + Settings.gas[NUM_OFFSET_DILUENT + i].depth_meter = data[4]; + return 0x4d; +} + +uint8_t getDiluent(int i,uint8_t * data) +{ + data[0] = Settings.gas[NUM_OFFSET_DILUENT + i].oxygen_percentage; + data[1] = Settings.gas[NUM_OFFSET_DILUENT + i].helium_percentage; + data[2] = hwOS4_to_hwOS_GasType(Settings.gas[NUM_OFFSET_DILUENT + i].note.uw); + data[3] = Settings.gas[NUM_OFFSET_DILUENT + i].depth_meter; + return 0x4d; +} + +uint8_t setSetpoint(int i,uint8_t * data) +{ + if(!checkValue(data[1],50,160)) + return ERROR_; + if(!checkValue(data[2],0,250)) + return ERROR_; + + Settings.setpoint[i].setpoint_cbar = data[1]; + Settings.setpoint[i].depth_meter = data[2]; + return 0x4d; +} + +uint8_t getSetpoint(int i,uint8_t * data) +{ + data[0] = Settings.setpoint[i].setpoint_cbar; + data[1] = Settings.setpoint[i].depth_meter; + return 0x4d; +} + +uint8_t checkValue(uint8_t value,uint8_t from, uint8_t to) +{ + if(value >= from && value <= to) + return 1; + return 0; +} + +uint8_t writeData(uint8_t * data) +{ + uint32_t newSensitivity; + uint16_t newDuration, newOffset; + uint8_t newStopDepth; + + switch(data[0]) + { + case 0x10: + return setGas(1,data); + case 0x11: + return setGas(2,data); + case 0x12: + return setGas(3,data); + case 0x13: + return setGas(4,data); + case 0x14: + return setGas(5,data); + case 0x15: + return setDiluent(1,data); + case 0x16: + return setDiluent(2,data); + case 0x17: + return setDiluent(3,data); + case 0x18: + return setDiluent(4,data); + case 0x19: + return setDiluent(5,data); + case 0x1A: + return setSetpoint(1,data); + case 0x1B: + return setSetpoint(2,data); + case 0x1C: + return setSetpoint(3,data); + case 0x1D: + return setSetpoint(4,data); + case 0x1E: + return setSetpoint(5,data); + case 0x1F: + if(!checkValue(data[2],0,1)) + return ERROR_; + Settings.CCR_Mode = data[1]; + break; + case 0x20: + if(!checkValue(data[1],0,3)) + return ERROR_; + Settings.dive_mode = data[1]; + break; + case 0x21: + if(!checkValue(data[1],1,2)) + return ERROR_; + Settings.deco_type.ub.standard = data[1] & 0x0F; + //Settings.deco_type.ub.alternative = (data[1] & 0xF0) >> 4; + break; + case 0x22: + if(!checkValue(data[1],100,190)) + return ERROR_; + Settings.ppO2_max_std = data[1]; + break; + case 0x23: + if(!checkValue(data[1],15,15)) + return ERROR_; + Settings.ppO2_min = data[1]; + break; + case 0x24: + if(!checkValue(data[1],0,15)) + return ERROR_; + Settings.future_TTS = data[1]; + break; + case 0x25: + if(!checkValue(data[1],10,99)) + return ERROR_; + Settings.GF_low = data[1]; + break; + case 0x26: + if(!checkValue(data[1],45,99)) + return ERROR_; + Settings.GF_high = data[1]; + break; + case 0x27: + if(!checkValue(data[1],10,99)) + return ERROR_; + Settings.aGF_low = data[1]; + break; + case 0x28: + if(!checkValue(data[1],45,99)) + return ERROR_; + Settings.aGF_high = data[1]; + break; + case 0x29: + if(!checkValue(data[1],0,5)) + return ERROR_; + Settings.VPM_conservatism.ub.standard = data[1]; + break; + case 0x2A: + case 0x2B: + return ERROR_; + case 0x2C: + if(!checkValue(data[1],3,9)) + return ERROR_; + Settings.last_stop_depth_meter = data[1]; + break; + case 0x2D: + if(!checkValue(data[1],0,4)) + return ERROR_; + Settings.brightness = data[1]; + break; + case 0x2E: + if(!checkValue(data[1],0,1)) + return ERROR_; + Settings.nonMetricalSystem = data[1]; + break; + case 0x2F: + return ERROR_; + case 0x30: + if(!checkValue(data[1],0,4)) + return ERROR_; + Settings.salinity = data[1]; + break; + case 0x31: + if(!checkValue(data[1],0,3)) + return ERROR_; + Settings.tX_colorscheme = data[1]; + GFX_use_colorscheme(Settings.tX_colorscheme); + break; + case 0x32: + if(!checkValue(data[1],0,4)) + return ERROR_; + Settings.selected_language = data[1]; + break; + case 0x33: + if(!checkValue(data[1],0,2)) + return ERROR_; + Settings.date_format = data[1]; + break; + case 0x34: + return ERROR_; + case 0x35: + if(data[1] & 0x80) + { + data[1] = ~(data[1]); + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.offsetPressure_mbar = 0 - data[1]; + } + else + { + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.offsetPressure_mbar = data[1]; + } + break; + case 0x36: + if(!checkValue(data[1],0,1)) + return ERROR_; + if(data[1]) + Settings.safetystopDuration = settingsGetPointerStandard()->safetystopDuration; + else + Settings.safetystopDuration = 0; + break; + case 0x37: + return ERROR_; + case 0x38: + if(!checkValue(data[1],0,1)) + return ERROR_; + Settings.fallbackToFixedSetpoint = data[1]; + break; + case 0x39: + return ERROR_; + case 0x3A: + if(!checkValue(data[1],70,110)) + return ERROR_; + newSensitivity = data[1]; + settingsHelperButtonSens_keepPercentageValues(newSensitivity, settingsGetPointer()->ButtonResponsiveness); + setButtonResponsiveness(Settings.ButtonResponsiveness); + break; + case 0x3B: + // value between 0 and 127 + if(buttonBalanceTranslatorHexToArray(data[1], settingsGetPointer()->buttonBalance)) + { + settingsHelperButtonSens_keepPercentageValues(settingsGetPointer()->ButtonResponsiveness[3], settingsGetPointer()->ButtonResponsiveness); + } + else // value >= 128 (bit 7 set) factory reset + { + getButtonFactorDefaults(&settingsGetPointer()->ButtonResponsiveness[3], settingsGetPointer()->buttonBalance); + settingsHelperButtonSens_keepPercentageValues(settingsGetPointerStandard()->ButtonResponsiveness[3], settingsGetPointer()->ButtonResponsiveness); + } + // valid for both: + setButtonResponsiveness(Settings.ButtonResponsiveness); + break; + case 0x3C: + if(!checkValue(data[1],5,50)) + return ERROR_; + Settings.gasConsumption_bottom_l_min = data[1]; + break; + case 0x3D: + if(!checkValue(data[1],5,50)) + return ERROR_; + Settings.gasConsumption_deco_l_min = data[1]; + break; + case 0x3E: + if(!checkValue(data[1],5,50)) + return ERROR_; + Settings.gasConsumption_travel_l_min = data[1]; + break; + case 0x3F: + case 0x40: + return ERROR_; + case 0x41: + if(!checkValue(data[1],0,1)) + return ERROR_; + Settings.alwaysShowPPO2 = data[1]; + break; + case 0x42: + if(data[1] & 0x80) + { + data[1] = ~(data[1]); + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.offsetTemperature_centigrad = 0 - data[1]; + } + else + { + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.offsetTemperature_centigrad = data[1]; + } + break; + case 0x43: + if(!checkValue(data[1],60,255)) + return ERROR_; + newDuration = (uint16_t)data[1] + 59; + newDuration /= 60; + Settings.safetystopDuration = (uint8_t)newDuration; + break; + case 0x44: + if(!checkValue(data[1],21,61)) + return ERROR_; + newStopDepth = data[1] + 9; + if(newStopDepth > 60) + newStopDepth = 60; + newStopDepth /= 10; + Settings.safetystopDepth = newStopDepth; + break; + case 0x45: + case 0x46: + return ERROR_; + case 0x47: + newOffset = data[2] * 256; + newOffset += data[1]; + if(newOffset > 9000) + return ERROR_; + Settings.logbookOffset = newOffset; + break; + case 0x70: + if(!checkValue(data[1],0,1)) + return ERROR_; + Settings.showDebugInfo = data[1]; + break; + case 0x71: + if(!checkValue(data[1],0,(EXTRADISPLAY_END - 1))) + return ERROR_; + Settings.extraDisplay = data[1]; + break; + case 0x72: + if(!checkValue(data[1],0,8)) + return ERROR_; + Settings.tX_customViewPrimary = data[1]; + break; + case 0x73: + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.tX_customViewTimeout = data[1]; + break; + case 0x74: + if(!checkValue(data[1],1,7)) + return ERROR_; + Settings.tX_userselectedLeftLowerCornerPrimary = data[1]; + break; + case 0x75: + if(!checkValue(data[1],0,20)) + return ERROR_; + Settings.tX_userselectedLeftLowerCornerTimeout = data[1]; + break; + } + return 0; +} + + +uint8_t readDataLimits__8and16BitValues_4and7BytesOutput(uint8_t what, uint8_t * data) +{ + enum JeanDoParameterType { + PARAM_UNKNOWN = 0, + PARAM_INT15 = 1, + PARAM_INT8, + PARAM_DECI, + PARAM_CENTI, + PARAM_MILI, + PARAM_PERCENT, + PARAM_SEC, + PARAM_COLOR, + PARAM_BOOL, + PARAM_ENUM, + PARAM_SIGNED = 128, + PARAM_SDECI = PARAM_SIGNED|PARAM_DECI, + PARAM_SSEC = PARAM_SIGNED|PARAM_SEC, + PARAM_SINT = PARAM_SIGNED|PARAM_INT8 + }; + +// uint32_t buttonSensitivity; + uint16_t newDuration; + + uint8_t datacounter = 0; + + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + datacounter = 0; + + switch(what) + { + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 4; + data[datacounter++] = settingsGetPointerStandard()->gas[1].oxygen_percentage; + data[datacounter++] = 100; + break; + + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 4; + data[datacounter++] = settingsGetPointerStandard()->gas[1].oxygen_percentage; + data[datacounter++] = 100; + break; + + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + data[datacounter++] = PARAM_CENTI; + data[datacounter++] = 50; + data[datacounter++] = settingsGetPointerStandard()->setpoint[1].setpoint_cbar; + data[datacounter++] = 160; + break; + + case 0x1F: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->CCR_Mode; + data[datacounter++] = 1; + break; + + case 0x20: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->dive_mode; + data[datacounter++] = 3; + break; + + case 0x21: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 1; + data[datacounter++] = settingsGetPointerStandard()->deco_type.ub.standard; + data[datacounter++] = 2; + break; + + case 0x22: + data[datacounter++] = PARAM_CENTI; + data[datacounter++] = 100; + data[datacounter++] = settingsGetPointerStandard()->ppO2_max_std; + data[datacounter++] = 190; + break; + + case 0x23: + data[datacounter++] = PARAM_CENTI; + data[datacounter++] = 15; + data[datacounter++] = settingsGetPointerStandard()->ppO2_min; + data[datacounter++] = 15; + break; + + case 0x24: + data[datacounter++] = PARAM_INT8; // minutes + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->future_TTS; + data[datacounter++] = 15; + break; + + case 0x25: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 10; + data[datacounter++] = settingsGetPointerStandard()->GF_low; + data[datacounter++] = 99; + break; + + case 0x26: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 45; + data[datacounter++] = settingsGetPointerStandard()->GF_high; + data[datacounter++] = 99; + break; + + case 0x27: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 10; + data[datacounter++] = settingsGetPointerStandard()->aGF_low; + data[datacounter++] = 99; + break; + + case 0x28: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 45; + data[datacounter++] = settingsGetPointerStandard()->aGF_high; + data[datacounter++] = 99; + break; + + case 0x29: + data[datacounter++] = PARAM_INT8; // conservatism +0 .. +5 + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->VPM_conservatism.ub.standard; + data[datacounter++] = 5; + break; + + case 0x2A: + case 0x2B: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 100; + data[datacounter++] = 100;// saturation, desaturation, settingsGetPointerStandard()->; + data[datacounter++] = 100; + break; + + case 0x2C: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 3; + data[datacounter++] = settingsGetPointerStandard()->last_stop_depth_meter; + data[datacounter++] = 9; + break; + + case 0x2D: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->brightness; + data[datacounter++] = 4; + break; + + case 0x2E: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->nonMetricalSystem; + data[datacounter++] = 1; + break; + + case 0x2F: + data[datacounter++] = PARAM_INT8; // Sampling rate logbook + data[datacounter++] = 2; + data[datacounter++] = 2; + data[datacounter++] = 2; + break; + + case 0x30: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->salinity; + data[datacounter++] = 4; + break; + + case 0x31: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->tX_colorscheme; + data[datacounter++] = 3; + break; + + case 0x32: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->selected_language; + data[datacounter++] = 1; + break; + + case 0x33: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->date_format; + data[datacounter++] = 2; + break; + + case 0x34: + data[datacounter++] = PARAM_UNKNOWN ; + data[datacounter++] = 0; + data[datacounter++] = 0; // compass gain, is unknown,, settingsGetPointerStandard()->; + data[datacounter++] = 0; + break; + + case 0x35: + data[datacounter++] = PARAM_SINT; + data[datacounter++] = (uint8_t)(256 - 20); // == -20 + if(settingsGetPointerStandard()->offsetPressure_mbar < 0) + data[datacounter++] = (uint8_t)(127 - settingsGetPointerStandard()->offsetPressure_mbar); + else + data[datacounter++] = settingsGetPointerStandard()->offsetPressure_mbar; + data[datacounter++] = 20; + break; + + case 0x36: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 0; + if(settingsGetPointerStandard()->safetystopDuration) + data[datacounter++] = 1; + else + data[datacounter++] = 0; + data[datacounter++] = 1; + break; + + case 0x37: + data[datacounter++] = PARAM_UNKNOWN ; + data[datacounter++] = 0; + data[datacounter++] = 0; // Set calibration gas, not possible with optical + data[datacounter++] = 0; + break; + + case 0x38: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->fallbackToFixedSetpoint; + data[datacounter++] = 1; + break; + + case 0x39: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 0; + data[datacounter++] = 0; // flipscreen, not yet :-) settingsGetPointerStandard()->; + data[datacounter++] = 0; + break; + + case 0x3A: + data[datacounter++] = PARAM_PERCENT; + data[datacounter++] = 70; + data[datacounter++] = settingsGetPointerStandard()->ButtonResponsiveness[3]; + data[datacounter++] = 110; + break; + + case 0x3B: + data[datacounter++] = PARAM_UNKNOWN; + data[datacounter++] = 0; + data[datacounter++] = buttonBalanceTranslateArrayOutHex(settingsGetPointerStandard()->buttonBalance); + data[datacounter++] = 128; + break; + + case 0x3C: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 5; + data[datacounter++] = settingsGetPointerStandard()->gasConsumption_bottom_l_min; + data[datacounter++] = 50; + break; + + case 0x3D: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 5; + data[datacounter++] = settingsGetPointerStandard()->gasConsumption_deco_l_min; + data[datacounter++] = 50; + break; + + case 0x3E: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 5; + data[datacounter++] = settingsGetPointerStandard()->gasConsumption_travel_l_min; + data[datacounter++] = 50; + break; + + case 0x3F: + data[datacounter++] = PARAM_UNKNOWN; + data[datacounter++] = 0; + data[datacounter++] = 0; // Dynamic ascend rate, not yet :-) settingsGetPointerStandard()->; + data[datacounter++] = 0; + break; + + case 0x40: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 1; + data[datacounter++] = 1; // Graphical speed indicator; + data[datacounter++] = 1; + break; + + case 0x41: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->alwaysShowPPO2; + data[datacounter++] = 1; + break; + + case 0x42: + data[datacounter++] = PARAM_SIGNED|PARAM_CENTI; + data[datacounter++] = (uint8_t)(256 - 20); // == -20 + if(settingsGetPointerStandard()->offsetTemperature_centigrad < 0) + data[datacounter++] = (uint8_t)(127 - settingsGetPointerStandard()->offsetTemperature_centigrad); + else + data[datacounter++] = settingsGetPointerStandard()->offsetTemperature_centigrad; + data[datacounter++] = 20; + break; + + case 0x43: + newDuration = settingsGetPointerStandard()->safetystopDuration; + newDuration *= 60; + if(newDuration > 255) + newDuration = 255; + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 60; // coud be 1 minute instead + data[datacounter++] = (uint8_t)newDuration; + data[datacounter++] = 255; // could be 5 minutes instead + break; + + case 0x44: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 30; // coud be 3 meter instead + data[datacounter++] = settingsGetPointerStandard()->safetystopDepth * 10; + data[datacounter++] = 60; // could be 6 meter instead + break; + + case 0x45: + case 0x46: + data[datacounter++] = PARAM_UNKNOWN; + data[datacounter++] = 0; + data[datacounter++] = 0; // SafetyStop End Depth and SafetyStop Reset Depth + data[datacounter++] = 0; + break; + + case 0x47: + data[datacounter++] = PARAM_INT15; + data[datacounter++] = 0; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->logbookOffset & 0xFF; + data[datacounter++] = settingsGetPointerStandard()->logbookOffset / 0xFF; + data[datacounter++] = 9000 & 0xFF; + data[datacounter++] = 9000 / 0xFF; + break; + + case 0x70: + data[datacounter++] = PARAM_BOOL; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->showDebugInfo; + data[datacounter++] = 1; + break; + + case 0x71: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->extraDisplay; + data[datacounter++] = (EXTRADISPLAY_END - 1); + break; + + case 0x72: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->tX_customViewPrimary; + data[datacounter++] = 8; + break; + + case 0x73: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->tX_customViewTimeout; + data[datacounter++] = 60; + break; + + case 0x74: + data[datacounter++] = PARAM_ENUM; + data[datacounter++] = 1; + data[datacounter++] = settingsGetPointerStandard()->tX_userselectedLeftLowerCornerPrimary; + data[datacounter++] = 7; + break; + + case 0x75: + data[datacounter++] = PARAM_INT8; + data[datacounter++] = 0; + data[datacounter++] = settingsGetPointerStandard()->tX_userselectedLeftLowerCornerTimeout; + data[datacounter++] = 60; + break; + } + + if(datacounter == 0) + { + data[datacounter++] = PARAM_UNKNOWN; + data[datacounter++] = 0; + data[datacounter++] = 0; // SafetyStop End Depth and SafetyStop Reset Depth + data[datacounter++] = 0; + } + + return datacounter; +} + + +uint8_t readData(uint8_t what, uint8_t * data) +{ + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + switch(what) + { + case 0x10: + return getGas(1,data); + case 0x11: + return getGas(2,data); + case 0x12: + return getGas(3,data); + case 0x13: + return getGas(4,data); + case 0x14: + return getGas(5,data); + case 0x15: + return getDiluent(1,data); + case 0x16: + return getDiluent(2,data); + case 0x17: + return getDiluent(3,data); + case 0x18: + return getDiluent(4,data); + case 0x19: + return getDiluent(5,data); + case 0x1A: + return getSetpoint(1,data); + case 0x1B: + return getSetpoint(2,data); + case 0x1C: + return getSetpoint(3,data); + case 0x1D: + return getSetpoint(4,data); + case 0x1E: + return getSetpoint(5,data); + case 0x1F: + data[0] = Settings.CCR_Mode; + break; + case 0x20: + data[0] = Settings.dive_mode; + break; + case 0x21: + data[0] = Settings.deco_type.ub.standard; + break; + case 0x22: + data[0] = Settings.ppO2_max_std; + break; + case 0x23: + data[0] = Settings.ppO2_min; + break; + case 0x24: + data[0] = Settings.future_TTS; + break; + case 0x25: + data[0] = Settings.GF_low; + break; + case 0x26: + data[0] = Settings.GF_high; + break; + case 0x27: + data[0] = Settings.aGF_low; + break; + case 0x28: + data[0] = Settings.aGF_high; + break; + case 0x29: + data[0] = Settings.VPM_conservatism.ub.standard; + break; + case 0x2A: + case 0x2B: + data[0] = 100; + break; + case 0x2C: + data[0] = Settings.last_stop_depth_meter; + break; + case 0x2D: + data[0] = Settings.brightness; + break; + case 0x2E: + data[0] = Settings.nonMetricalSystem; + break; + case 0x2F: + data[0] = 0; // 0 == 2 sec sampling rate + break; + case 0x30: + data[0] = Settings.salinity; + break; + case 0x31: + data[0] = Settings.tX_colorscheme; + break; + case 0x32: + data[0] = Settings.selected_language; + break; + case 0x33: + data[0] = Settings.date_format; + break; + case 0x34: + data[0] = 7; // gain should be always 7 as far as I understand the code in RTE + break; + case 0x35: + data[0] = Settings.offsetPressure_mbar; + break; + case 0x36: + if(Settings.safetystopDepth) + data[0] = 1; + else + data[0] = 0; + break; + case 0x37: + data[0] = 0; // calibration gas %O2 -> 0 no gas :-) + break; + case 0x38: + data[0] = Settings.fallbackToFixedSetpoint; + break; + case 0x39: + data[0] = 0; // flip screen + break; + case 0x3A: + data[0] = Settings.ButtonResponsiveness[3]; + break; + case 0x3B: + data[0] = buttonBalanceTranslateArrayOutHex(settingsGetPointer()->buttonBalance); + break; + case 0x3C: + data[0] = Settings.gasConsumption_bottom_l_min; + break; + case 0x3D: + data[0] = Settings.gasConsumption_deco_l_min; + break; + case 0x3E: + data[0] = Settings.gasConsumption_travel_l_min; + break; + case 0x3F: + data[0] = 0; // fixed ascend rate 10 m/min + break; + case 0x40: + data[0] = 1; // graphical speed indicator + break; + case 0x41: + data[0] = Settings.alwaysShowPPO2; + break; + case 0x42: + data[0] = Settings.offsetTemperature_centigrad; + break; + case 0x43: + if(Settings.safetystopDuration > 4) + data[0] = 255; // seconds + else + data[0] = 60 * Settings.safetystopDuration; + break; + case 0x44: + data[0] = Settings.safetystopDepth * 10; // cbar instead of meter + break; + case 0x45: + if(Settings.safetystopDepth == 3) + data[0] = 20; // cbar + else + data[0] = 30; // cbar + break; + case 0x46: + data[0] = 10; // reset at 10 meter as far as I understood + break; + case 0x47: + data[0] = Settings.logbookOffset & 0xFF; + data[1] = Settings.logbookOffset / 0xFF; + break; + case 0x70: + data[0] = Settings.showDebugInfo; + break; + case 0x71: + data[0] = Settings.extraDisplay; + break; + case 0x72: + data[0] = Settings.tX_customViewPrimary; + break; + case 0x73: + data[0] = Settings.tX_customViewTimeout; + break; + case 0x74: + data[0] = Settings.tX_userselectedLeftLowerCornerPrimary; + break; + case 0x75: + data[0] = Settings.tX_userselectedLeftLowerCornerTimeout; + break; + } + return 0x4D; +} + + +uint8_t RTEminimum_required_high(void) +{ + return RTErequiredHigh; +} +uint8_t RTEminimum_required_low(void) +{ + return RTErequiredLow; +} + +uint8_t FONTminimum_required_high(void) +{ + return FONTrequiredHigh; +} +uint8_t FONTminimum_required_low(void) +{ + return FONTrequiredLow; +} + + +void setActualRTEversion(uint8_t high, uint8_t low) +{ + RTEactualHigh = high; + RTEactualLow = low; +} + + +void getActualRTEandFONTversion(uint8_t *RTEhigh, uint8_t *RTElow, uint8_t *FONThigh, uint8_t *FONTlow) +{ + if(RTEhigh && RTElow) + { + *RTEhigh = RTEactualHigh; + *RTElow = RTEactualLow; + } + if(FONThigh && FONTlow) + { + *FONThigh = *(uint8_t *)0x08132000; + *FONTlow = *(uint8_t *)0x08132001; + } +} + + +uint8_t getLicence(void) +{ + //return 0xFF; + //return LICENCEBONEX; + return hardwareDataGetPointer()->primaryLicence; +} + + +void firmwareGetDate(RTC_DateTypeDef *SdateOutput) +{ + SdateOutput->Year = firmwareDataGetPointer()->release_year; + SdateOutput->Month = firmwareDataGetPointer()->release_month; + SdateOutput->Date = firmwareDataGetPointer()->release_day; +} + + +// this should use device specific values stored in OTPROG ROM soon +void getButtonFactorDefaults(uint8_t* basePercentage, uint8_t* buttonBalanceArray) +{ + *basePercentage = settingsGetPointerStandard()->ButtonResponsiveness[3]; + + for(int i=0;i<3;i++) + { + buttonBalanceArray[i] = settingsGetPointerStandard()->buttonBalance[i]; + } +} + + +uint8_t buttonBalanceTranslatorHexToArray(uint8_t hexValue, uint8_t* outputArray) +{ + if(hexValue > 127) + return 0; + // internal order: 0 = right, 1 = center, 2 = left + // external order: Factory,left,center,right + outputArray[0] = 2 + (hexValue & 0x03); + hexValue /= 4; + outputArray[1] = 2 + (hexValue & 0x03); + hexValue /= 4; + outputArray[2] = 2 + (hexValue & 0x03); + + return 1; +} + + +uint8_t buttonBalanceTranslateArrayOutHex(const uint8_t* inputArray) +{ + uint8_t hexValue = 0; + + if(inputArray[2] > 2) + { + hexValue += inputArray[2] - 2; + } + hexValue *= 4; + + if(inputArray[1] > 2) + { + hexValue += inputArray[1] - 2; + } + hexValue *= 4; + if(inputArray[0] > 2) + { + hexValue += inputArray[0] - 2; + } + return hexValue; +} + +void settingsWriteFactoryDefaults(uint8_t inputValueRaw, uint8_t *inputBalanceArray) +{ + if((inputValueRaw >= 70) && (inputValueRaw <= 110)) + { + Settings.FactoryButtonBase = inputValueRaw; + } + for(int i=0;i<3;i++) + { + if((inputBalanceArray[i] >= 2) && (inputBalanceArray[i] <= 5)) + { + Settings.FactoryButtonBalance[i] = inputBalanceArray[i]; + } + } +} + + +/** + ****************************************************************************** + * @brief settingsHelperButtonSens. / make 32 bit input to three buttons + storage value in [3] + * @author heinrichs weikamp gmbh + * @version V 01 + * @date 19-Sept-2016 + ****************************************************************************** + * + * @param inputValueRaw: + * @param outArray4Values: [0] is right, [1] is center, [2] is left, [3] is original value with zero balance + * @retval None + */ +void settingsHelperButtonSens_keepPercentageValues(uint32_t inputValueRaw, uint8_t *outArray4Values) +{ + uint32_t newSensitivity; + + if(inputValueRaw > 110) + { + inputValueRaw = 110; + } + else + if(inputValueRaw < 70) + { + inputValueRaw = 70; + } + + // the unbalanced value + outArray4Values[3] = inputValueRaw; + + // the balanced values + for(int i=0;i<3;i++) + { + newSensitivity = inputValueRaw; + switch(settingsGetPointer()->buttonBalance[i]) + { + case 1: // should not be an option hw 170508 + newSensitivity -= 20; + break; + case 2: + newSensitivity -= 10; + break; + default: + break; + case 4: + newSensitivity += 10; + break; + case 5: + newSensitivity += 20; + break; + } + + if(newSensitivity > 110) + { + newSensitivity = 110; + } + outArray4Values[i] = newSensitivity; + } +} + + +/** + ****************************************************************************** + * @brief settingsHelperButtonSens_translate_to_hwOS_values. / make 32 bit input to three buttons + storage value in [3] + * @author heinrichs weikamp gmbh + * @version V 01 + * @date 19-Sept-2016 + ****************************************************************************** + * + * @param inputValueRaw: + * @param outArray4Values: [0] is right, [1] is center, [2] is left, [3] is original value with zero balance + * @retval None + */ +void settingsHelperButtonSens_original_translate_to_hwOS_values(const uint32_t inputValueRaw, uint8_t *outArray4Values) +{ + uint32_t newSensitivity; + + for(int i=0;i<3;i++) + { + newSensitivity = inputValueRaw; + switch(settingsGetPointer()->buttonBalance[i]) + { + case 1: + newSensitivity -= 20; + break; + case 2: + newSensitivity -= 10; + break; + default: + break; + case 4: + newSensitivity += 10; + break; + case 5: + newSensitivity += 20; + break; + } + + if(newSensitivity > 100) + { + if(newSensitivity <= 105) + newSensitivity = 10; + else + newSensitivity = 7; + } + else + { + newSensitivity *= 24; + newSensitivity = 2400 - newSensitivity; + newSensitivity /= 10; + + newSensitivity += 15; + if(newSensitivity > 255) + newSensitivity = 255; + } + outArray4Values[i] = newSensitivity; + } + + // the unbalanced value + newSensitivity = inputValueRaw; + if(newSensitivity > 100) + { + if(newSensitivity <= 105) + newSensitivity = 10; + else + newSensitivity = 7; + } + else + { + newSensitivity *= 24; + newSensitivity = 2400 - newSensitivity; + newSensitivity /= 10; + + newSensitivity += 15; + if(newSensitivity > 255) + newSensitivity = 255; + } + outArray4Values[3] = newSensitivity; +} + + +/** + ****************************************************************************** + * @brief settingsHelperButtonSens_translate_percentage_to_hwOS_values. + * @author heinrichs weikamp gmbh + * @version V 01 + * @date 6-March-2017 + ****************************************************************************** + * + * @param inputValuePercentage with buttonBalance included + * @retval PIC compatible value + */ +uint8_t settingsHelperButtonSens_translate_percentage_to_hwOS_values(uint8_t inputValuePercentage) +{ + uint32_t newSensitivity = inputValuePercentage; + + if(newSensitivity > 100) + { + if(newSensitivity <= 105) + newSensitivity = 10; + else + newSensitivity = 7; + } + else + { + newSensitivity *= 24; + newSensitivity = 2400 - newSensitivity; + newSensitivity /= 10; + + newSensitivity += 15; + if(newSensitivity > 255) + newSensitivity = 255; + } + return (uint8_t)newSensitivity; +} + + +/** + ****************************************************************************** + * @brief settingsHelperButtonSens_translate_hwOS_values_to_percentage. + * @author heinrichs weikamp gmbh + * @version V 01 + * @date 6-March-2017 + ****************************************************************************** + * + * @param PIC compatible value + * @retval Percentage + */ +uint8_t settingsHelperButtonSens_translate_hwOS_values_to_percentage(uint8_t inputValuePIC) +{ + if(inputValuePIC >= 15) + { + return(uint8_t)((25500 - (inputValuePIC)*100) / 240); + } + else + { + if(inputValuePIC >= 10) + { + return 105; + } + else + { + return 110; + } + } +}