# HG changeset patch # User heinrichs weikamp # Date 1639492570 -3600 # Node ID 1b995079c045245fd29ec3ae431a5126584cd2a7 # Parent 87bee7cc77b3eeecb395daa7cd17e5ac4f67c073 PSCR Mode diff -r 87bee7cc77b3 -r 1b995079c045 Common/Inc/data_central.h --- a/Common/Inc/data_central.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Common/Inc/data_central.h Tue Dec 14 15:36:10 2021 +0100 @@ -50,7 +50,8 @@ uint8_t setPoint_cbar; uint8_t change_during_ascent_depth_meter_otherwise_zero; uint8_t GasIdInSettings; - uint8_t temp1_for16bitalign; + uint8_t AppliedDiveMode; + float pscr_factor; } SGas; typedef struct @@ -75,6 +76,13 @@ uint8_t data[12]; } SDataWireless; + +typedef struct +{ + uint16_t CO2_ppm; + uint16_t signalStrength; +} SCO2Sensor; + /* Main structs -------------------------------------------------------------*/ @@ -187,6 +195,8 @@ uint16_t ambient_light_level; SDataWireless wireless_data[4]; uint8_t buttonPICdata[4]; + SCO2Sensor CO2_data; + /* by create DiveSettings() and by setActualGas() * is send to Small CPU2 for nitrogen calculation @@ -221,6 +231,9 @@ float ppO2Sensor_bar[3]; float sensorVoltage_mV[3]; float HUD_battery_voltage_V; + +/* for PSCR Mode */ + float ppo2Simulated_bar; } SLifeData; @@ -323,6 +336,9 @@ */ float internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero; uint16_t compassHeading; + + uint8_t pscr_o2_drop; + uint8_t pscr_lung_ratio; } SDiveSettings; enum CHARGE_STATUS{ @@ -454,4 +470,6 @@ _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData); +uint8_t isLoopMode(uint8_t Mode); + #endif // DATA_CENTRAL_H diff -r 87bee7cc77b3 -r 1b995079c045 Common/Inc/data_exchange.h --- a/Common/Inc/data_exchange.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Common/Inc/data_exchange.h Tue Dec 14 15:36:10 2021 +0100 @@ -31,6 +31,10 @@ #include "settings.h" #include "stm32f4xx_hal.h" +/* Command definitions for contral of external interface */ +#define EXT_INTERFACE_33V_ON (0x8000u) /* Bit set to enable 3.3V power interface */ +#define EXT_INTERFACE_CO2_CALIB (0x0001u) /* Request calibration of CO2Sensor */ + enum MODE { MODE_SURFACE = 0, @@ -80,9 +84,11 @@ #define CRBUTTON (0x01) #define CRDATE (0x02) #define CRTIME (0x04) -#define CRCLEARDECO (0x08) -#define CRCOMPASS (0x10) -#define CRDEVICEDATA (0x20) +#define CRCLEARDECO (0x08) +#define CRCOMPASS (0x10) +#define CRDEVICEDATA (0x20) +#define CRBATTERY (0x40) +#define CRACCIDENT (0x80) typedef union{ confirmbit8_t ub; @@ -148,7 +154,10 @@ uint16_t ambient_light_level; uint16_t SPARE_ALIGN32; float extADC_voltage[3]; - uint8_t SPARE_OldWireless[50]; /* 64 - 12 for extADC */ + uint16_t CO2_ppm; + uint16_t CO2_signalStrength; + uint16_t externalInterface_CmdAnswer; + uint8_t SPARE_OldWireless[44]; /* 64 - 12 for extADC - 6 for CO2 */ // PIC data uint8_t button_setting[4]; /* see dependency to SLiveData->buttonPICdata */ uint8_t SPARE1; @@ -166,8 +175,7 @@ int8_t offsetPressureSensor_mbar; int8_t offsetTemperatureSensor_centiDegree; - uint8_t SPARE1; - uint8_t SPARE2; + uint16_t externalInterface_Cmd; float UNUSED1[16-1];//VPM_adjusted_critical_radius_he[16]; float UNUSED2[16];//VPM_adjusted_critical_radius_n2[16]; diff -r 87bee7cc77b3 -r 1b995079c045 Common/Inc/decom.h --- a/Common/Inc/decom.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Common/Inc/decom.h Tue Dec 14 15:36:10 2021 +0100 @@ -46,6 +46,8 @@ void test_decom_CreateGasChangeList(void); float decom_calc_ppO2(const float ambiant_pressure_bar, const SGas* pGas); +float decom_calc_SimppO2(float ambiant_pressure_bar, const SGas* pGas); +float decom_calc_SimppO2_O2based(float ambiant_pressure_bar, uint8_t O2PerCent, float factor); void decom_oxygen_calculate_otu(float* oxygen_otu, float pressure_oxygen_real); void decom_oxygen_calculate_otu_degrade(float* oxygen_otu, long seconds_since_last_dive); void decom_oxygen_calculate_cns_degrade(float* oxygen_cns, long seconds_since_last_dive); diff -r 87bee7cc77b3 -r 1b995079c045 Common/Inc/settings.h --- a/Common/Inc/settings.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Common/Inc/settings.h Tue Dec 14 15:36:10 2021 +0100 @@ -47,11 +47,13 @@ #define CCRMODE_FixedSetpoint 0 #define CCRMODE_Sensors 1 +#define CCRMODE_Simulation 2 #define DIVEMODE_OC 0 #define DIVEMODE_CCR 1 #define DIVEMODE_Gauge 2 #define DIVEMODE_Apnea 3 +#define DIVEMODE_PSCR 4 #define GF_MODE 1 #define VPM_MODE 2 @@ -74,6 +76,12 @@ #define MAX_SCRUBBER_TIME (500u) #define MIN_PPO2_SP_CBAR (40u) +#define PSCR_MAX_O2_DROP (15u) +#define PSCR_MIN_LUNG_RATIO (5u) +#define PSCR_MAX_LUNG_RATIO (20u) + +#define FUTURE_SPARE_SIZE (29u) /* Applied for reuse of old, not used, scooter block (was 32 bytes)*/ + typedef enum { O2_SENSOR_SOURCE_OPTIC = 0, @@ -202,13 +210,10 @@ uint8_t bluetoothActive; /* will be set to zero on each startup at the moment */ uint8_t safetystopDepth; uint32_t updateSettingsAllowedFromHeader; - uint8_t scooterControl; - uint8_t scooterDrag; - uint8_t scooterLoad; - uint8_t scooterNumberOfBatteries; - uint16_t scooterBattSize; - uint8_t scooterSPARE1[7]; - uint8_t scooterSPARE2[19]; + uint8_t pscr_lung_ratio; /* redefined in 0xFFFF0020 */ + uint8_t pscr_o2_drop; /* redefined in 0xFFFF0020 */ + uint8_t co2_sensor_active; /* redefined in 0xFFFF0021 */ + uint8_t Future_SPARE[FUTURE_SPARE_SIZE]; /* redefined in 0xFFFF0020 (old scooter Block was 32 byte)*/ // new in 0xFFFF0006 uint8_t ppo2sensors_deactivated; uint8_t tX_colorscheme; @@ -340,4 +345,7 @@ uint8_t settingsHelperButtonSens_translate_percentage_to_hwOS_values(uint8_t inputValuePercentage); uint8_t settingsHelperButtonSens_translate_hwOS_values_to_percentage(uint8_t inputValuePIC); +void reset_SettingWarning(); +uint8_t isSettingsWarning(); + #endif // SETTINGS_H diff -r 87bee7cc77b3 -r 1b995079c045 Common/Src/decom.c --- a/Common/Src/decom.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Common/Src/decom.c Tue Dec 14 15:36:10 2021 +0100 @@ -217,24 +217,34 @@ float ppo2_fraction_setpoint; float diluent_divisor; - *fraction_nitrogen = ((float)pGas->nitrogen_percentage) / 100.0f; *fraction_helium = ((float)pGas->helium_percentage) / 100.0f; - if(!pGas->setPoint_cbar) - return; + if(pGas->AppliedDiveMode == DIVEMODE_CCR) + { + // continue with CCR + fraction_all_inertgases = *fraction_nitrogen + *fraction_helium; - // continue with CCR - fraction_all_inertgases = *fraction_nitrogen + *fraction_helium; + ppo2_fraction_setpoint = (float)pGas->setPoint_cbar/ (100 * ambient_pressure_bar); + + diluent_divisor = (1.0f - ppo2_fraction_setpoint) / fraction_all_inertgases; + if(diluent_divisor < 0) + diluent_divisor = 0; - ppo2_fraction_setpoint = (float)pGas->setPoint_cbar/ (100 * ambient_pressure_bar); + *fraction_nitrogen *= diluent_divisor; + *fraction_helium *= diluent_divisor; + } + if(pGas->AppliedDiveMode == DIVEMODE_PSCR) + { + fraction_all_inertgases = *fraction_nitrogen + *fraction_helium; + ppo2_fraction_setpoint = decom_calc_SimppO2(ambient_pressure_bar, pGas) / ambient_pressure_bar; + diluent_divisor = (1.0f - ppo2_fraction_setpoint) / fraction_all_inertgases; + if(diluent_divisor < 0) + diluent_divisor = 0; - diluent_divisor = (1.0f - ppo2_fraction_setpoint) / fraction_all_inertgases; - if(diluent_divisor < 0) - diluent_divisor = 0; - - *fraction_nitrogen *= diluent_divisor; - *fraction_helium *= diluent_divisor; + *fraction_nitrogen *= diluent_divisor; + *fraction_helium *= diluent_divisor; + } } @@ -618,13 +628,13 @@ pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].helium_percentage; pInput->decogaslist[count].helium_percentage = pInput->gas[i].helium_percentage; pInput->decogaslist[count].GasIdInSettings = i; - + pInput->decogaslist[count].AppliedDiveMode = DIVEMODE_OC; } } } else { - //divmode CCR + //divmode CCR or PSCR for(i=6; i <= 10; i++) { if(pInput->gas[i].note.ub.active && pInput->gas[i].depth_meter @@ -642,55 +652,69 @@ } pInput->decogaslist[count].change_during_ascent_depth_meter_otherwise_zero = pInput->gas[i].depth_meter; pInput->decogaslist[count].nitrogen_percentage = 100; - pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage; + if(pInput->diveMode == DIVEMODE_PSCR) + { + pInput->decogaslist[count].AppliedDiveMode = DIVEMODE_PSCR; + pInput->decogaslist[count].setPoint_cbar = decom_calc_SimppO2_O2based((float)(pInput->gas[i].depth_meter / 10.0 + 1.0), pInput->gas[i].oxygen_percentage, pInput->decogaslist[count].pscr_factor ) * 100; + pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage; + } + else + { + pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage; + } pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].helium_percentage; pInput->decogaslist[count].helium_percentage = pInput->gas[i].helium_percentage; pInput->decogaslist[count].GasIdInSettings = i; } } - /* Include Setpoint Changes */ - for(j=0; j <= count; j++) + if(pInput->diveMode == DIVEMODE_CCR) { - uint8_t depth = 0; - uint8_t changedepth = 0; - char newSetpoint; - if(j == 0) - { - depth = pLifeData->depth_meter; - } - else - { - //no setpointchange ? - pInput->decogaslist[j].setPoint_cbar = pInput->decogaslist[j - 1].setPoint_cbar; - depth = pInput->decogaslist[j].change_during_ascent_depth_meter_otherwise_zero + 0.1f; - } - /* Setpoint change at the same depth as gas changes */ - if(nextSetpointChange(pInput,depth + 1, &changedepth,&newSetpoint) && changedepth == depth) + /* Include Setpoint Changes */ + for(j=0; j <= count; j++) { - pInput->decogaslist[j].setPoint_cbar = newSetpoint; - } - /* Setpoint changes inbetween gas changes */ - while(nextSetpointChange(pInput, depth, &changedepth,&newSetpoint) - && ( - ( (j < count) && (changedepth > pInput->decogaslist[j + 1].change_during_ascent_depth_meter_otherwise_zero)) - || ((j == count) && (changedepth > 0)) - )) - { - //Include new entry with setpoint change in decogaslist - for(int k = count; k > j; k--) + uint8_t depth = 0; + uint8_t changedepth = 0; + char newSetpoint; + + pInput->decogaslist[j].AppliedDiveMode = DIVEMODE_CCR; + if(j == 0) + { + depth = pLifeData->depth_meter; + } + else + { + //no setpointchange ? + pInput->decogaslist[j].setPoint_cbar = pInput->decogaslist[j - 1].setPoint_cbar; + depth = pInput->decogaslist[j].change_during_ascent_depth_meter_otherwise_zero + 0.1f; + } + /* Setpoint change at the same depth as gas changes */ + if(nextSetpointChange(pInput,depth + 1, &changedepth,&newSetpoint) && changedepth == depth) { - pInput->decogaslist[k+1] = pInput->decogaslist[k]; + pInput->decogaslist[j].setPoint_cbar = newSetpoint; } - pInput->decogaslist[j + 1] = pInput->decogaslist[j]; - pInput->decogaslist[j + 1].setPoint_cbar = newSetpoint; - j++; - count++; - depth = changedepth; + /* Setpoint changes inbetween gas changes */ + while(nextSetpointChange(pInput, depth, &changedepth,&newSetpoint) + && ( + ( (j < count) && (changedepth > pInput->decogaslist[j + 1].change_during_ascent_depth_meter_otherwise_zero)) + || ((j == count) && (changedepth > 0)) + )) + { + //Include new entry with setpoint change in decogaslist + for(int k = count; k > j; k--) + { + pInput->decogaslist[k+1] = pInput->decogaslist[k]; + } + pInput->decogaslist[j + 1] = pInput->decogaslist[j]; + pInput->decogaslist[j + 1].setPoint_cbar = newSetpoint; + j++; + count++; + depth = changedepth; + } + } } - } } void test_decom_CreateGasChangeList(void) @@ -1022,16 +1046,51 @@ float decom_calc_ppO2(const float ambiant_pressure_bar, const SGas* pGas) { - float percent_N2 = 0; + float percent_N2 = 0; float percent_He = 0; float percent_O2 = 0; - decom_get_inert_gases(ambiant_pressure_bar, pGas, &percent_N2, &percent_He); - percent_O2 = 1 - percent_N2 - percent_He; - return (ambiant_pressure_bar - WATER_VAPOUR_PRESSURE) * percent_O2; + decom_get_inert_gases(ambiant_pressure_bar, pGas, &percent_N2, &percent_He); + percent_O2 = 1 - percent_N2 - percent_He; + + return (ambiant_pressure_bar - WATER_VAPOUR_PRESSURE) * percent_O2; } +float decom_calc_SimppO2(float ambiant_pressure_bar, const SGas* pGas) +{ + float o2Ratio = 0.0; + float inertGasRatio = 0.0; + float simulatedPSCRppo2 = 0.0; + + o2Ratio = (100.0 - pGas->nitrogen_percentage - pGas->helium_percentage) / 100.0; + inertGasRatio = 1.0 - o2Ratio; + simulatedPSCRppo2 = (ambiant_pressure_bar - WATER_VAPOUR_PRESSURE) * o2Ratio; + simulatedPSCRppo2 -= (inertGasRatio * pGas->pscr_factor); + if(simulatedPSCRppo2 < 0.0) + { + simulatedPSCRppo2 = 0.0; + } + return simulatedPSCRppo2; +} + +float decom_calc_SimppO2_O2based(float ambiant_pressure_bar, uint8_t O2PerCent, float factor) +{ + float o2Ratio = 0.0; + float inertGasRatio = 0.0; + float simulatedPSCRppo2 = 0.0; + + o2Ratio = O2PerCent / 100.0; + inertGasRatio = 1.0 - o2Ratio; + simulatedPSCRppo2 = (ambiant_pressure_bar - WATER_VAPOUR_PRESSURE) * o2Ratio; + simulatedPSCRppo2 -= (inertGasRatio * factor); + if(simulatedPSCRppo2 < 0.0) + { + simulatedPSCRppo2 = 0.0; + } + return simulatedPSCRppo2; +} + uint8_t decom_get_actual_deco_stop(SDiveState* pDiveState) { SDecoinfo* pDecoinfo; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/configuration.h --- a/Discovery/Inc/configuration.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/configuration.h Tue Dec 14 15:36:10 2021 +0100 @@ -61,4 +61,13 @@ /* Enable to have PPO2 adjustments in T3 sensor view during dive simulation */ /* #define ENABLE_T3_PPO_SIM */ +/* Enable to have PSCR functionality available */ +/* #define ENABLE_PSCR_MODE */ + +/* Enable to have CO2 sensor functionality available */ +/* #define ENABLE_CO2_SUPPORT */ + +/* Enable if you are using sensors with a voltage range 8..16 mV at surface / air level */ +/* #define ENABLE_ALTERNATIVE_SENSORTYP */ + #endif diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/data_exchange_main.h --- a/Discovery/Inc/data_exchange_main.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/data_exchange_main.h Tue Dec 14 15:36:10 2021 +0100 @@ -45,7 +45,7 @@ void DataEX_copy_to_LifeData(_Bool *modeChangeFlag); void DataEX_copy_to_deco(void); void DateEx_copy_to_dataOut(void); -void DataEX_merge_deviceData(void); +void DataEX_merge_devicedata(void); uint32_t DataEX_lost_connection_count(void); void DataEX_control_connection_while_asking_for_sleep(void); uint8_t DataEX_check_RTE_version__needs_update(void); @@ -56,4 +56,6 @@ uint16_t DataEX_debug_data(uint16_t *dataOut20x5); +void DataEX_setExtInterface_Cmd(uint16_t Cmd); + #endif /* DATA_EXCHANGE_MAIN_H */ diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/t7.h --- a/Discovery/Inc/t7.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/t7.h Tue Dec 14 15:36:10 2021 +0100 @@ -49,6 +49,9 @@ #ifdef ENABLE_BOTTLE_SENSOR LCC_BottleBar, #endif +#ifdef ENABLE_PSCR_MODE + LCC_SimPpo2, +#endif LLC_END } customview_llc_t; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/tMenuEditXtra.h --- a/Discovery/Inc/tMenuEditXtra.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/tMenuEditXtra.h Tue Dec 14 15:36:10 2021 +0100 @@ -33,5 +33,6 @@ void openEdit_Xtra(uint8_t line); void refresh_CompassHeading(void); +void refresh_CO2Data(void); #endif /* TMENU_EDIT_XTRA_H */ diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/tStructure.h --- a/Discovery/Inc/tStructure.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/tStructure.h Tue Dec 14 15:36:10 2021 +0100 @@ -195,10 +195,13 @@ #define StMXTRA_CompassHeading _MB(2,4,2,1,0) /* SURFACE MODE */ - #define StMXTRA_ScrubTimer_Max_Minutes _MB(2,4,1,1,0) - #define StMXTRA_ScrubTimer_Reset _MB(2,4,2,1,0) - #define StMXTRA_ScrubTimer_OP_Mode _MB(2,4,3,1,0) - +#define StMXTRA_ScrubTimer_Max_Minutes _MB(2,4,1,1,0) +#define StMXTRA_ScrubTimer_Reset _MB(2,4,2,1,0) +#define StMXTRA_ScrubTimer_OP_Mode _MB(2,4,3,1,0) +#define StMXTRA_PSCR_O2_Drop _MB(2,4,4,1,0) +#define StMXTRA_PSCR_LUNG_RATIO _MB(2,4,5,1,0) +#define StMXTRA_CO2_Sensor _MB(2,4,6,1,0) +#define StMXTRA_CO2_Sensor_Calib _MB(2,4,6,2,0) /* PAGE 5 */ #define StMDECO _MB(2,5,0,0,0) @@ -216,12 +219,13 @@ /* PAGE 5 EDIT FIELD CONTENT */ #define StMDECO1_OC _MB(2,5,1,1,0) #define StMDECO1_CC _MB(2,5,1,2,0) -#define StMDECO1_Apnea _MB(2,5,1,3,0) -#define StMDECO1_Gauge _MB(2,5,1,4,0) +#define StMDECO1_Apnea _MB(2,5,1,3,0) +#define StMDECO1_Gauge _MB(2,5,1,4,0) +#define StMDECO1_PSCR _MB(2,5,1,5,0) #define StMDECO2_CCRmode _MB(2,5,2,1,0) #define StMDECO3_PPO2Max _MB(2,5,3,1,0) -#define StMDECO4_SafetyStop _MB(2,5,4,1,0) +#define StMDECO4_SafetyStop _MB(2,5,4,1,0) #define StMDECO5_FUTURE _MB(2,5,5,1,0) #define StMDECO6_SALINITY _MB(2,5,6,1,0) @@ -310,7 +314,8 @@ #define StMSYS5_RebootMainCPU _MB(2,8,5,9,0) #define StMSYS5_ScreenTest _MB(2,8,5,10,0) #define StMSYS5_SetFactoryBC _MB(2,8,5,11,0) -#define StMSYS5_SetSampleIndx _MB(2,8,5,12,0) +#define StMSYS5_ResetBluetooth _MB(2,8,5,12,0) +#define StMSYS5_SetSampleIndx _MB(2,8,5,13,0) /* PAGE 9 */ diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Inc/text_multilanguage.h --- a/Discovery/Inc/text_multilanguage.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Inc/text_multilanguage.h Tue Dec 14 15:36:10 2021 +0100 @@ -119,6 +119,7 @@ TXT_ClosedCircuit, TXT_Apnoe, TXT_Gauge, + TXT_PSClosedCircuit, TXT_Sensor, TXT_FixedSP, TXT_Decoparameters, @@ -141,6 +142,10 @@ TXT_ScrubTimeReset, TXT_ScrubTimeMode, TXT_Percent, + TXT_PSCRO2Drop, + TXT_PSCRLungRatio, + TXT_SimPpo2, + TXT_CO2Sensor, /* */ TXT_END, @@ -308,6 +313,7 @@ TXT2BYTE_Maintenance, TXT2BYTE_SetBatteryCharge, TXT2BYTE_SetFactoryDefaults, + TXT2BYTE_ResetBluetooth, TXT2BYTE_SetSampleIndex, TXT2BYTE_Reboot, TXT2BYTE_ButtonLeft, @@ -335,6 +341,8 @@ TXT2BYTE_Normal, TXT2BYTE_Maximum, + TXT2BYTE_CheckSettings, + TXT2BYTE_END }; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/base.c --- a/Discovery/Src/base.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/base.c Tue Dec 14 15:36:10 2021 +0100 @@ -507,6 +507,7 @@ { DoDisplayRefresh = 0; + updateSetpointStateUsed(); if(stateUsed == stateSimGetPointer()) { simulation_UpdateLifeData(1); @@ -588,8 +589,6 @@ case BaseHome: case BaseMenu: case BaseInfo: - updateSetpointStateUsed(); - DateEx_copy_to_dataOut(); DataEX_copy_to_LifeData(&modeChange); //foto session :-) stateRealGetPointerWrite()->lifeData.battery_charge = 99; @@ -769,17 +768,20 @@ } } else if ((status.page == PageDive) && (status.line != 0)) { - if (pSettings->extraDisplay == EXTRADISPLAY_BIGFONT) + if(get_globalState() == StDMENU) { - pSettings->design = 3; - if(pSettings->MotionDetection == MOTION_DETECT_SECTOR) + if (pSettings->extraDisplay == EXTRADISPLAY_BIGFONT) { - DefineSectorCount(CUSTOMER_DEFINED_VIEWS); - MapCVToSector(); + pSettings->design = 3; + if(pSettings->MotionDetection == MOTION_DETECT_SECTOR) + { + DefineSectorCount(CUSTOMER_DEFINED_VIEWS); + MapCVToSector(); + } } + else if (pSettings->extraDisplay == EXTRADISPLAY_DECOGAME) + pSettings->design = 4; } - else if (pSettings->extraDisplay == EXTRADISPLAY_DECOGAME) - pSettings->design = 4; set_globalState(StD); } else @@ -1733,7 +1735,7 @@ } } // stuff before and new @161121 CCR-sensor limit 10 minutes - if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) && (settingsGetPointer()->CCR_Mode == CCRMODE_Sensors)) + if(isLoopMode(settingsGetPointer()->dive_mode) && (settingsGetPointer()->CCR_Mode == CCRMODE_Sensors)) { timeout_limit_Surface_in_seconds = settingsGetPointer()->timeoutSurfacemodeWithSensors; } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/check_warning.c --- a/Discovery/Src/check_warning.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/check_warning.c Tue Dec 14 15:36:10 2021 +0100 @@ -128,7 +128,7 @@ /* Private functions ---------------------------------------------------------*/ static int8_t check_fallback(SDiveState * pDiveState) { - if(fallback && ((pDiveState->mode != MODE_DIVE) || (pDiveState->diveSettings.diveMode != DIVEMODE_CCR))) + if(fallback && ((pDiveState->mode != MODE_DIVE) || (!isLoopMode(pDiveState->diveSettings.diveMode)))) fallback = 0; pDiveState->warnings.fallback = fallback; @@ -181,7 +181,7 @@ pDiveState->warnings.sensorOutOfBounds[1] = 0; pDiveState->warnings.sensorOutOfBounds[2] = 0; - if((pDiveState->diveSettings.diveMode == DIVEMODE_CCR) && (pDiveState->diveSettings.CCR_Mode == CCRMODE_Sensors)) + if(isLoopMode(pDiveState->diveSettings.diveMode) && (pDiveState->diveSettings.CCR_Mode == CCRMODE_Sensors)) if(settingsGetPointer()->ppo2sensors_source == O2_SENSOR_SOURCE_OPTIC) { @@ -218,7 +218,7 @@ betterGasIdLocal = pLifeData->actualGas.GasIdInSettings; bestGasDepth = 255; - if(pDiveSettings->diveMode == DIVEMODE_CCR) + if(isLoopMode(pDiveSettings->diveMode)) gasIdOffset = NUM_OFFSET_DILUENT; else gasIdOffset = 0; @@ -285,33 +285,31 @@ { pDiveState->warnings.betterSetpoint = 0; betterSetpointId = 0; - - if((stateUsed->mode != MODE_DIVE) || (pDiveState->diveSettings.diveMode != DIVEMODE_CCR) || (pDiveState->diveSettings.CCR_Mode != CCRMODE_FixedSetpoint)) - { - return 0; - } - uint8_t bestSetpointDepth = 0; // travel the deeper, the better uint8_t betterSetpointIdLocal = 0; // nothing better - if(!actualLeftMaxDepth(pDiveState)) /* travel gases */ + + if((stateUsed->mode == MODE_DIVE) && (pDiveState->diveSettings.diveMode == DIVEMODE_CCR)) { - for(int i=1; i<=NUM_GASES; i++) + if(!actualLeftMaxDepth(pDiveState)) /* travel gases */ { - if( (pDiveState->diveSettings.setpoint[i].note.ub.active) - && (pDiveState->diveSettings.setpoint[i].depth_meter) - && (pDiveState->diveSettings.setpoint[i].depth_meter <= ( pDiveState->lifeData.depth_meter + 0.01f )) - && (pDiveState->diveSettings.setpoint[i].depth_meter >= bestSetpointDepth) - ) - { - betterSetpointIdLocal = i; - bestSetpointDepth = pDiveState->diveSettings.setpoint[i].depth_meter; - } - } - if((betterSetpointIdLocal) && (pDiveState->diveSettings.setpoint[betterSetpointIdLocal].setpoint_cbar != pDiveState->lifeData.actualGas.setPoint_cbar)) - { - betterSetpointId = betterSetpointIdLocal; - pDiveState->warnings.betterSetpoint = 1; + for(int i=1; i<=NUM_GASES; i++) + { + if( (pDiveState->diveSettings.setpoint[i].note.ub.active) + && (pDiveState->diveSettings.setpoint[i].depth_meter) + && (pDiveState->diveSettings.setpoint[i].depth_meter <= ( pDiveState->lifeData.depth_meter + 0.01f )) + && (pDiveState->diveSettings.setpoint[i].depth_meter >= bestSetpointDepth) + ) + { + betterSetpointIdLocal = i; + bestSetpointDepth = pDiveState->diveSettings.setpoint[i].depth_meter; + } + } + if((betterSetpointIdLocal) && (pDiveState->diveSettings.setpoint[betterSetpointIdLocal].setpoint_cbar != pDiveState->lifeData.actualGas.setPoint_cbar)) + { + betterSetpointId = betterSetpointIdLocal; + pDiveState->warnings.betterSetpoint = 1; + } } } return pDiveState->warnings.betterSetpoint; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/data_central.c --- a/Discovery/Src/data_central.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/data_central.c Tue Dec 14 15:36:10 2021 +0100 @@ -71,6 +71,7 @@ #include "ostc.h" // for button adjust on hw testboard 1 #include "tCCR.h" #include "crcmodel.h" +#include "configuration.h" static SDiveState stateReal = { 0 }; SDiveState stateSim = { 0 }; @@ -316,6 +317,7 @@ void createDiveSettings(void) { + int i; SSettings* pSettings = settingsGetPointer(); setActualGasFirst(&stateReal.lifeData); @@ -325,7 +327,13 @@ stateReal.diveSettings.diveMode = pSettings->dive_mode; stateReal.diveSettings.CCR_Mode = pSettings->CCR_Mode; - if(stateReal.diveSettings.diveMode == DIVEMODE_CCR) + if((stateReal.diveSettings.diveMode == DIVEMODE_PSCR) && (stateReal.diveSettings.CCR_Mode == CCRMODE_FixedSetpoint)) + { + /* TODO: update selection of sensor used on/off (currently sensor/fixpoint). As PSCR has no fixed setpoint change to simulated ppo2 if sensors are not active */ + stateReal.diveSettings.CCR_Mode = CCRMODE_Simulation; + } + + if(isLoopMode(stateReal.diveSettings.diveMode)) stateReal.diveSettings.ccrOption = 1; else stateReal.diveSettings.ccrOption = 0; @@ -341,13 +349,24 @@ stateReal.diveSettings.ppo2sensors_deactivated = pSettings->ppo2sensors_deactivated; stateReal.diveSettings.future_TTS_minutes = pSettings->future_TTS; + stateReal.diveSettings.pscr_lung_ratio = pSettings->pscr_lung_ratio; + stateReal.diveSettings.pscr_o2_drop = pSettings->pscr_o2_drop; + + if(stateReal.diveSettings.diveMode == DIVEMODE_PSCR) + { + for(i=0; i<5; i++) + { + stateReal.diveSettings.decogaslist[i].pscr_factor = 1.0 / stateReal.diveSettings.pscr_lung_ratio * stateReal.diveSettings.pscr_o2_drop; + } + } + decom_CreateGasChangeList(&stateReal.diveSettings, &stateReal.lifeData); // decogaslist stateReal.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; /* for safety */ stateReal.diveSettings.input_second_to_last_stop_depth_bar = stateReal.diveSettings.last_stop_depth_bar + stateReal.diveSettings.input_next_stop_increment_depth_bar; /* and the proper calc */ - for(int i = 1; i <10; i++) + for(i = 1; i <10; i++) { if(stateReal.diveSettings.input_next_stop_increment_depth_bar * i > stateReal.diveSettings.last_stop_depth_bar) { @@ -389,9 +408,11 @@ } + + void updateSetpointStateUsed(void) { - if(stateUsed->diveSettings.diveMode != DIVEMODE_CCR) + if(!isLoopMode(stateReal.diveSettings.diveMode)) { stateUsedWrite->lifeData.actualGas.setPoint_cbar = 0; stateUsedWrite->lifeData.ppO2 = decom_calc_ppO2(stateUsed->lifeData.pressure_ambient_bar, &stateUsed->lifeData.actualGas); @@ -402,7 +423,17 @@ { stateUsedWrite->lifeData.actualGas.setPoint_cbar = get_ppO2SensorWeightedResult_cbar(); } - +#ifdef ENABLE_PSCR_MODE + if(stateUsed->diveSettings.diveMode == DIVEMODE_PSCR) /* calculate a ppO2 value based on assumptions ( transfered approach from hwos code) */ + { + stateUsedWrite->lifeData.ppo2Simulated_bar = decom_calc_SimppO2_O2based(stateUsed->lifeData.pressure_ambient_bar, stateReal.diveSettings.gas[stateUsed->lifeData.actualGas.GasIdInSettings].oxygen_percentage, stateUsed->lifeData.actualGas.pscr_factor); + if(stateUsed->diveSettings.CCR_Mode == CCRMODE_Simulation) + { + stateUsedWrite->lifeData.actualGas.setPoint_cbar = stateUsedWrite->lifeData.ppo2Simulated_bar * 100; + } + } +#endif + /* limit calculated value to the physically possible if needed */ if((stateUsed->lifeData.pressure_ambient_bar * 100) < stateUsed->lifeData.actualGas.setPoint_cbar) stateUsedWrite->lifeData.ppO2 = stateUsed->lifeData.pressure_ambient_bar; else @@ -417,7 +448,7 @@ uint8_t gasId = 0; uint8_t setpoint_cbar = 0; - if(pSettings->dive_mode == DIVEMODE_CCR) + if(isLoopMode(pSettings->dive_mode)) { setpoint_cbar = pSettings->setpoint[1].setpoint_cbar; start = NUM_OFFSET_DILUENT+1; @@ -449,6 +480,7 @@ lifeData->actualGas.helium_percentage =0; lifeData->actualGas.setPoint_cbar = 0; lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; + lifeData->actualGas.AppliedDiveMode = stateUsed->diveSettings.diveMode; } @@ -466,8 +498,9 @@ lifeData->actualGas.helium_percentage = pSettings->gas[gasId].helium_percentage; lifeData->actualGas.setPoint_cbar = setpoint_cbar; lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; - - if((pSettings->dive_mode == DIVEMODE_CCR) && (gasId > NUM_OFFSET_DILUENT)) + lifeData->actualGas.AppliedDiveMode = pSettings->dive_mode; + lifeData->actualGas.pscr_factor = 1.0 / pSettings->pscr_lung_ratio * pSettings->pscr_o2_drop; + if(isLoopMode(pSettings->dive_mode) && (gasId > NUM_OFFSET_DILUENT)) lifeData->lastDiluent_GasIdInSettings = gasId; } @@ -525,7 +558,7 @@ lifeData->actualGas.helium_percentage = helium; lifeData->actualGas.setPoint_cbar = setpoint_cbar; lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; - + lifeData->actualGas.AppliedDiveMode = stateUsed->diveSettings.diveMode; } void setButtonResponsiveness(uint8_t *ButtonSensitivyList) @@ -814,3 +847,12 @@ return compass_compensated; } +uint8_t isLoopMode(uint8_t Mode) +{ + uint8_t retVal = 0; + if((Mode == DIVEMODE_CCR) || (Mode == DIVEMODE_PSCR)) + { + retVal = 1; + } + return retVal; +} diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/data_exchange_main.c --- a/Discovery/Src/data_exchange_main.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/data_exchange_main.c Tue Dec 14 15:36:10 2021 +0100 @@ -72,7 +72,7 @@ #include "buehlmann.h" #include "externLogbookFlash.h" -//#define TESTBENCH +/* #define TESTBENCH */ /* Exported variables --------------------------------------------------------*/ static uint8_t wasPowerOn = 0; @@ -94,6 +94,8 @@ static uint8_t DeviceDataUpdated = 0; +static uint16_t externalInterface_Cmd = 0; + /* Private types -------------------------------------------------------------*/ #define UNKNOWN_TIME_HOURS 1 #define UNKNOWN_TIME_MINUTES 0 @@ -181,12 +183,12 @@ if(getDeviceDataWasSend) { dataOut.getDeviceDataNow = 0; - requestNecessary.ub.devicedata = 1; } getDeviceDataWasSend = 0; if(dataOut.getDeviceDataNow) { getDeviceDataWasSend = 1; + requestNecessary.ub.devicedata = 1; } if(setEndDiveWasSend) @@ -203,40 +205,39 @@ if(setAccidentFlagWasSend) { dataOut.setAccidentFlag = 0; - requestNecessary.ub.accident = 1; } setAccidentFlagWasSend = 0; if(dataOut.setAccidentFlag) { setAccidentFlagWasSend = 1; + requestNecessary.ub.accident = 1; } if(setDateWasSend) { dataOut.setDateNow = 0; - requestNecessary.ub.date = 1; } setDateWasSend = 0; if(dataOut.setDateNow) { setDateWasSend = 1; + requestNecessary.ub.date = 1; } if(setTimeWasSend) { dataOut.setTimeNow = 0; - requestNecessary.ub.time = 1; } setTimeWasSend = 0; if(dataOut.setTimeNow) { setTimeWasSend = 1; + requestNecessary.ub.time = 1; } if(calibrateCompassWasSend) { dataOut.calibrateCompassNow = 0; - requestNecessary.ub.compass = 1; } calibrateCompassWasSend = 0; if(dataOut.calibrateCompassNow) @@ -247,22 +248,23 @@ if(clearDecoWasSend) { dataOut.clearDecoNow = 0; - requestNecessary.ub.clearDeco = 1; + requestNecessary.ub.compass = 1; } if(dataOut.clearDecoNow) { clearDecoWasSend = 1; + requestNecessary.ub.clearDeco = 1; } if(setButtonSensitivityWasSend) { dataOut.setButtonSensitivityNow = 0; - requestNecessary.ub.button = 1; } setButtonSensitivityWasSend = 0; if(dataOut.setButtonSensitivityNow) { setButtonSensitivityWasSend = 1; + requestNecessary.ub.button = 1; } } @@ -389,6 +391,13 @@ dataOut.data.offsetPressureSensor_mbar = settings->offsetPressure_mbar; dataOut.data.offsetTemperatureSensor_centiDegree = settings->offsetTemperature_centigrad; + if(settings->co2_sensor_active) + { + externalInterface_Cmd |= EXT_INTERFACE_33V_ON; + } + dataOut.data.externalInterface_Cmd = externalInterface_Cmd; + externalInterface_Cmd = 0; + if((hardwareDataGetPointer()->primarySerial <= 32) || (((hardwareDataGetPointer()->primarySerial == 72) && (hardwareDataGetPointer()->secondarySerial == 15)))) { dataOut.revisionHardware = 0x00; @@ -773,9 +782,14 @@ void DataEX_copy_to_LifeData(_Bool *modeChangeFlag) { + static uint16_t getDeviceDataAfterStartOfMainCPU = 20; + SDiveState *pStateReal = stateRealGetPointerWrite(); - static uint16_t getDeviceDataAfterStartOfMainCPU = 20; uint8_t idx; + float meter = 0; + SSettings *pSettings; + + // wireless - �ltere daten aufr�umen #if 0 @@ -836,23 +850,46 @@ } } - /* new 151207 hw */ - if(requestNecessary.uw != 0) + if((requestNecessary.uw != 0) && (dataIn.confirmRequest.uw != 0)) { if(((dataIn.confirmRequest.uw) & CRBUTTON) != 0) { requestNecessary.ub.button = 0; } + if(((dataIn.confirmRequest.uw) & CRCLEARDECO) != 0) + { + requestNecessary.ub.clearDeco = 0; + } + if(((dataIn.confirmRequest.uw) & CRDATE) != 0) + { + requestNecessary.ub.date = 0; + } + if(((dataIn.confirmRequest.uw) & CRTIME) != 0) + { + requestNecessary.ub.time = 0; + } + if(((dataIn.confirmRequest.uw) & CRCOMPASS) != 0) + { + requestNecessary.ub.compass = 0; + } + if(((dataIn.confirmRequest.uw) & CRDEVICEDATA) != 0) + { + requestNecessary.ub.devicedata = 0; + } + if(((dataIn.confirmRequest.uw) & CRBATTERY) != 0) + { + requestNecessary.ub.batterygauge = 0; + } + if(((dataIn.confirmRequest.uw) & CRACCIDENT) != 0) + { + requestNecessary.ub.accident = 0; + } - if(requestNecessary.ub.button == 1) + if(requestNecessary.ub.button == 1) /* send button values to RTE */ { setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness); } } - requestNecessary.uw = 0; // clear all - - float meter = 0; - SSettings *pSettings; /* uint8_t IAmStolenPleaseKillMe; */ @@ -909,7 +946,6 @@ pStateReal->lifeData.dateBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_dr; pStateReal->lifeData.timeBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_tr; } - dataOut.setAccidentFlag = 0; if(pStateReal->data_old__lost_connection_to_slave == 0) { @@ -971,11 +1007,25 @@ pStateReal->lifeData.max_depth_meter = meter; } - if(dataIn.accidentFlags & ACCIDENT_DECOSTOP) - pStateReal->decoMissed_at_the_end_of_dive = 1; - if(dataIn.accidentFlags & ACCIDENT_CNS) - pStateReal->cnsHigh_at_the_end_of_dive = 1; - + if(requestNecessary.ub.clearDeco == 0) /* No "reset deco" is send to RTE ? */ + { + if(dataIn.accidentFlags & ACCIDENT_DECOSTOP) + { + pStateReal->decoMissed_at_the_end_of_dive = 1; + } + else + { + pStateReal->decoMissed_at_the_end_of_dive = 0; + } + if(dataIn.accidentFlags & ACCIDENT_CNS) + { + pStateReal->cnsHigh_at_the_end_of_dive = 1; + } + else + { + pStateReal->cnsHigh_at_the_end_of_dive = 0; + } + } pStateReal->lifeData.dive_time_seconds = (int32_t)dataIn.data[dataIn.boolTimeData].divetime_seconds; pStateReal->lifeData.dive_time_seconds_without_surface_time = (int32_t)dataIn.data[dataIn.boolTimeData].dive_time_seconds_without_surface_time; pStateReal->lifeData.counterSecondsShallowDepth = dataIn.data[dataIn.boolTimeData].counterSecondsShallowDepth; @@ -1030,6 +1080,10 @@ /* sensorErrors */ pStateReal->sensorErrorsRTE = dataIn.sensorErrors; + + /* data from CO2 sensor */ + pStateReal->lifeData.CO2_data.CO2_ppm = dataIn.data[0].CO2_ppm; + pStateReal->lifeData.CO2_data.signalStrength = dataIn.data[0].CO2_signalStrength; } /* apnea specials @@ -1205,3 +1259,10 @@ return retval; } + +void DataEX_setExtInterface_Cmd(uint16_t Cmd) +{ + externalInterface_Cmd = Cmd; + return; +} + diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/logbook.c --- a/Discovery/Src/logbook.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/logbook.c Tue Dec 14 15:36:10 2021 +0100 @@ -1002,7 +1002,7 @@ break; } firstgasid = i + 1; - if(header.diveMode == DIVEMODE_CCR) + if(isLoopMode(header.diveMode)) setPointLast = header.setpoint[0].setpoint_cbar; else setPointLast = 0; @@ -1166,6 +1166,10 @@ gas.setPoint_cbar = setPointVal; if(gasidVal > 0) { + if((gasidVal >= NUM_GASES) && (header.diveMode == DIVEMODE_PSCR)) /* in case gas switches the absolute gas ID is used => map to the 0..NUM_GASES index used in header */ + { + gasidVal -= NUM_GASES; + } gas.helium_percentage = header.gasordil[gasidVal - 1].helium_percentage; gas.nitrogen_percentage = 100 - gas.helium_percentage - header.gasordil[gasidVal - 1].oxygen_percentage; } @@ -1175,7 +1179,15 @@ gas.nitrogen_percentage = 100 - gas.helium_percentage - manualGasVal.percentageO2; } ambiant_pressure_bar =((float)(depthVal + header.surfacePressure_mbar))/1000; - ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas ); + + if(header.diveMode == DIVEMODE_PSCR) + { + ppO2 = decom_calc_SimppO2(ambiant_pressure_bar, &gas); + } + else /* open circuit calculation */ + { + ppO2 = decom_calc_ppO2(ambiant_pressure_bar, &gas); + } ppo2[iNum] = (uint16_t) ( ppO2 * 100); } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/settings.c --- a/Discovery/Src/settings.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/settings.c Tue Dec 14 15:36:10 2021 +0100 @@ -36,6 +36,8 @@ #include "t7.h" #include "data_central.h" +static uint8_t settingsWarning = 0; /* Active if setting values have been corrected */ + SSettings Settings; const uint8_t RTErequiredHigh = 2; @@ -85,10 +87,10 @@ * There might even be entries with fixed values that have no range */ const SSettings SettingsStandard = { - .header = 0xFFFF001F, + .header = 0xFFFF0021, .warning_blink_dsec = 8 * 2, .lastDiveLogId = 0, - .logFlashNextSampleStartAddress = 0, + .logFlashNextSampleStartAddress = SAMPLESTART, .gas[0].oxygen_percentage = 21, .gas[1].oxygen_percentage = 21, @@ -219,7 +221,7 @@ .ppO2_min = 15, .CNS_max = 90, .ascent_MeterPerMinute_max = 30, - .ascent_MeterPerMinute_showGraph = 7, + .ascent_MeterPerMinute_showGraph = 30, .future_TTS = 5, .GF_high = 85, .GF_low = 30, @@ -268,13 +270,9 @@ .bluetoothActive = 0, .safetystopDepth = 5, .updateSettingsAllowedFromHeader = 0xFFFF0002, - .scooterControl = 0, - .scooterDrag = 2, - .scooterLoad = 2, - .scooterNumberOfBatteries = 1, - .scooterBattSize = 760, - .scooterSPARE1[0] = 0, - .scooterSPARE2[0] = 0, + .pscr_lung_ratio = 10, + .pscr_o2_drop = 4, + .co2_sensor_active = 0, .ppo2sensors_deactivated = 0, .tX_colorscheme = 0, .tX_userselectedLeftLowerCornerPrimary = LLC_Temperature, @@ -371,8 +369,6 @@ SSettings* pSettings = settingsGetPointer(); const SSettings* pStandard = settingsGetPointerStandard(); - pSettings->scooterControl = 0; - /* Pointing to the old header data => set new data depending on what had been added since last version */ switch(pSettings->header) { @@ -433,15 +429,7 @@ 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: @@ -496,7 +484,21 @@ pSettings->ppo2sensors_calibCoeff[0] = 0.0; pSettings->ppo2sensors_calibCoeff[1] = 0.0; pSettings->ppo2sensors_calibCoeff[2] = 0.0; + pSettings->amPMTime = 0; // no break + case 0xFFFF001E: + pSettings->autoSetpoint = 0; + pSettings->scrubTimerMax = 0; + pSettings->scrubTimerCur = 0; + pSettings->scrubTimerMode = SCRUB_TIMER_OFF; + // no break + case 0xFFFF001F: + pSettings->pscr_lung_ratio = 10; + pSettings->pscr_o2_drop = 4; + // no break + case 0xFFFF0020: + pSettings->co2_sensor_active = 0; + // no break; default: pSettings->header = pStandard->header; break; // no break before!! @@ -536,6 +538,9 @@ uint8_t firstGasFoundOC = 0; uint8_t firstGasFoundCCR = 0; + + settingsWarning = 0; /* reset warning indicator */ + /* uint32_t header; */ @@ -564,7 +569,8 @@ 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_Apnea) && + (Settings.dive_mode != DIVEMODE_PSCR)) { Settings.dive_mode = DIVEMODE_OC; corrections++; @@ -618,9 +624,9 @@ } if(Settings.gas[i].note.ub.first) { - if(Settings.setpoint[i].note.ub.active != 1) + if(Settings.gas[i].note.ub.active != 1) { - Settings.setpoint[i].note.ub.active = 1; + Settings.gas[i].note.ub.active = 1; corrections++; } if(Settings.gas[i].note.ub.travel == 1) @@ -671,6 +677,7 @@ Settings.gas[1].note.ub.first = 1; Settings.gas[1].note.ub.travel = 0; Settings.gas[1].note.ub.deco = 0; + corrections++; } if(!firstGasFoundCCR) { @@ -678,6 +685,7 @@ 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; + corrections++; } /* SSetpointLine setpoint[1 + NUM_GASES]; */ @@ -747,6 +755,7 @@ /* uint8_t CCR_Mode; */ if( (Settings.CCR_Mode != CCRMODE_Sensors) && + (Settings.CCR_Mode != CCRMODE_Simulation) && (Settings.CCR_Mode != CCRMODE_FixedSetpoint)) { Settings.CCR_Mode = CCRMODE_FixedSetpoint; @@ -1461,10 +1470,36 @@ Settings.scrubTimerMode = SCRUB_TIMER_OFF; corrections++; } + + if((Settings.pscr_lung_ratio > PSCR_MAX_LUNG_RATIO) || (Settings.pscr_lung_ratio < PSCR_MIN_LUNG_RATIO)) + { + Settings.pscr_lung_ratio = 10; + corrections++; + } + if(Settings.pscr_o2_drop > PSCR_MAX_O2_DROP) + { + Settings.pscr_o2_drop = 4; + corrections++; + } + + if(Settings.co2_sensor_active > 1) + { + Settings.co2_sensor_active = 0; + corrections++; + } + + if(corrections) + { + settingsWarning = 1; + } + else + if(corrections > 255) - return 255; - else - return (uint8_t)corrections; + { + corrections = 255; + } + + return (uint8_t)corrections; } @@ -2921,3 +2956,13 @@ } } } + +void reset_SettingWarning() +{ + settingsWarning = 0; +} +inline uint8_t isSettingsWarning() +{ + return settingsWarning; +} + diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/show_logbook.c --- a/Discovery/Src/show_logbook.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/show_logbook.c Tue Dec 14 15:36:10 2021 +0100 @@ -35,6 +35,7 @@ #include "unit.h" #include "configuration.h" #include "logbook_miniLive.h" +#include "text_multilanguage.h" #include #include @@ -515,16 +516,19 @@ switch(logbookHeader.diveMode) { case DIVEMODE_OC: - snprintf(text,20,"open circuit"); + snprintf(text,20,"%c",TXT_OpenCircuit); break; case DIVEMODE_CCR: - snprintf(text,20,"closed circuit"); + snprintf(text,20,"%c",TXT_ClosedCircuit); break; case DIVEMODE_Gauge: - snprintf(text,20,"Gauge"); + snprintf(text,20,"%c",TXT_Gauge); break; case DIVEMODE_Apnea: - snprintf(text,20,"Apnea"); + snprintf(text,20,"%c",TXT_Apnoe); + break; + case DIVEMODE_PSCR: + snprintf(text,20,"%c",TXT_PSClosedCircuit); break; } Gfx_write_label_var(hgfx, 30, 250,60, &FontT42,CLUT_GasSensor4,text); @@ -886,6 +890,10 @@ { SWindowGimpStyle wintemp; SWindowGimpStyle winsmal; + uint8_t gasWasUsed[NUM_GASES * 2]; + int16_t index = 0; + uint8_t loopMode = 0; + wintemp.left = 50; wintemp.right = 799 - wintemp.left; wintemp.top = 50; @@ -899,6 +907,40 @@ uint8_t gasdata[1000]; dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + char msg[15]; + char gas_name[15]; + int j = 0; + + loopMode = isLoopMode(logbookHeader.diveMode); + + /* check if gas was used, independent from its active state */ + for(index = 0; index < NUM_GASES * 2; index++) + { + gasWasUsed[index] = 0; + } + for(index = 0; index < dataLength; index++) + { + if(loopMode) + { + if(gasdata[index] < NUM_GASES) /* the log entry starts with a ID in range 1..4 independend if diluent is used at start */ + { + gasdata[index] += NUM_GASES; + } + else + { + loopMode = 0; /* after the first gas change, no matter if diluent or bailout, the correct ID will be stored */ + } + } + if(gasdata[index] > 0) + { + gasWasUsed[gasdata[index]-1] = 1; /* The ID stored in the samples is starting with 1 (array[0] = gasID1) */ + } + else + { + gasWasUsed[0] = 1; + } + } + //--- print coordinate system & depth graph with gaschanges --- show_logbook_draw_depth_graph(hgfx, StepBackwards, &wintemp, 1, dataLength, depthdata, gasdata, NULL); @@ -906,21 +948,38 @@ winsmal.left = wintemp.right - 190; winsmal.right = winsmal.left + 150; - char msg[15]; - char gas_name[15]; - int j = 0; - for(int i = 4;i >= 0;i--) + loopMode = isLoopMode(logbookHeader.diveMode); + for(index = (2 * NUM_GASES) -1; index >= 0; index--) { - if(logbookHeader.gasordil[i].note.ub.active > 0) + if(gasWasUsed[index]) { j++; + if(j > 5) /* limit number of gases displayed to 5 */ + { + break; + } winsmal.top = wintemp.bottom - 5 - j * 26 ; winsmal.bottom = winsmal.top + 21 ; - uint8_t color = get_colour(i); + uint8_t color = get_colour(index); - print_gas_name(gas_name,15,logbookHeader.gasordil[i].oxygen_percentage,logbookHeader.gasordil[i].helium_percentage); - snprintf(msg,15,"G%i: %s",i + 1, gas_name); - //msg[10] = 0; + if(loopMode) + { + if(index < NUM_GASES) /* Switch to Bailout is not covered by log gas list */ + { + snprintf(gas_name,15,"Bailout"); + snprintf(msg,15,"G%d: %s",index +1, gas_name); + } + else + { + print_gas_name(gas_name,15,logbookHeader.gasordil[index-NUM_GASES].oxygen_percentage,logbookHeader.gasordil[index-NUM_GASES].helium_percentage); + snprintf(msg,15,"D%d: %s",index +1 - NUM_GASES, gas_name); + } + } + else + { + print_gas_name(gas_name,15,logbookHeader.gasordil[index].oxygen_percentage,logbookHeader.gasordil[index].helium_percentage); + snprintf(msg,15,"G%d: %s",index +1, gas_name); + } Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,msg); } } @@ -933,6 +992,26 @@ */ } +static uint8_t check_data_array_empty(uint16_t* pdata) +{ + uint8_t ret = 0; + uint8_t index = 0; + uint8_t emptyCnt = 0; + + for (index=0; index < 10; index++) /* read the first 10 data points. If all are 0 then the array is rated as empty */ + { + if(*(pdata+index) == 0) + { + emptyCnt++; + } + } + if(emptyCnt == 10) + { + ret = 1; + } + return ret; +} + static void show_logbook_logbook_show_log_page4(GFX_DrawCfgScreen *hgfx, uint8_t StepBackwards) { SWindowGimpStyle wintemp; SWindowGimpStyle winsmal; @@ -950,18 +1029,55 @@ uint16_t ppO2data[1000]; uint16_t sensor2[1000]; uint16_t sensor3[1000]; - uint16_t *setpoint = ppO2data; - uint16_t *sensor1 = ppO2data; + uint16_t *setpoint = ppO2data; + uint16_t *sensor1 = ppO2data; + uint8_t sensorDataAvailable[] = {0,0,0}; - if(logbookHeader.diveMode != DIVEMODE_CCR) + if(!isLoopMode(logbookHeader.diveMode)) dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); else { - if(logbookHeader.CCRmode == CCRMODE_FixedSetpoint) - dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - else - dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL, NULL, NULL); + switch(logbookHeader.CCRmode) + { + case CCRMODE_FixedSetpoint: + default: dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, setpoint, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + break; + case CCRMODE_Sensors: dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata, gasdata, NULL, NULL, NULL, sensor1, sensor2, sensor3, NULL, NULL, NULL, NULL, NULL); + if(!check_data_array_empty(sensor1)) + { + sensorDataAvailable[0] = 1; + } + if(!check_data_array_empty(sensor2)) + { + sensorDataAvailable[1] = 1; + } + if(!check_data_array_empty(sensor3)) + { + sensorDataAvailable[2] = 1; + } + if((logbookHeader.diveMode == DIVEMODE_PSCR) && (sensorDataAvailable[0] + sensorDataAvailable[1] + sensorDataAvailable[2] != 3)) /*insert sim data if not all three sensors are in use*/ + { + if(sensorDataAvailable[0] == 0) + { + logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + sensorDataAvailable[0] = 1; + } + else if(sensorDataAvailable[1] == 0) + { + logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + sensorDataAvailable[1] = 1; + } + else if(sensorDataAvailable[2] == 0) + { + logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, sensor3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + sensorDataAvailable[2] = 1; + } + } + break; + case CCRMODE_Simulation: dataLength = logbook_readSampleData(StepBackwards, 1000, depthdata,gasdata, NULL, ppO2data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + break; + } } @@ -999,14 +1115,25 @@ winsmal.left = 799 - 67;//wintemp.right -67; winsmal.right = winsmal.left;// + 45; - color = CLUT_LogbookTemperature;//LOGBOOK_GRAPH_DEPTH; - if(logbookHeader.diveMode != DIVEMODE_CCR) + color = CLUT_LogbookTemperature; + + if(!isLoopMode(logbookHeader.diveMode)) + { Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002PP O2"); + } else - if(logbookHeader.CCRmode != CCRMODE_Sensors) - Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002SETPOINT"); - else - Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002SENSORS"); + { + switch(logbookHeader.CCRmode) + { + case CCRMODE_FixedSetpoint: + default: Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002SETPOINT"); + break; + case CCRMODE_Sensors: Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002SENSORS"); + break; + case CCRMODE_Simulation: Gfx_write_label_var(hgfx, winsmal.left, winsmal.right,winsmal.top, &FontT24,color,"\002SIM PPO2"); + break; + } + } //*** PP O2 **************************************************** //calc lines and labels @@ -1019,7 +1146,7 @@ if(ppO2data[i]diveSettings.ppo2sensors_deactivated & (1<lifeData.ppO2Sensor_bar[i] == 0.0)) { - text[textpointer++] = '\031'; - text[textpointer++] = ' '; - text[textpointer++] = '-'; - text[textpointer++] = ' '; - text[textpointer++] = 0; +#ifdef ENABLE_PSCR_MODE + if((stateUsed->diveSettings.diveMode == DIVEMODE_PSCR) && (showSimPPO2) && (stateUsed->mode == MODE_DIVE)) /* display ppo2 sim in blue letters in case a slot is not used in the ppo2 custom view */ + { + text[textpointer++] = '\023'; + textpointer += snprintf(&text[textpointer],TEXTSIZE,"%.2f",stateUsed->lifeData.ppo2Simulated_bar); + showSimPPO2 = 0; + } + else +#endif + { + text[textpointer++] = '\031'; + text[textpointer++] = ' '; + text[textpointer++] = '-'; + text[textpointer++] = ' '; + text[textpointer++] = 0; + } } else { @@ -1279,7 +1293,7 @@ GFX_write_string(&FontT105,tXc1,text,0); - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (pSettings->dive_mode == DIVEMODE_CCR)) + if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && isLoopMode(pSettings->dive_mode)) { snprintf(text,TEXTSIZE,"\032\002\f%c",TXT_ScrubTime); GFX_write_string(&FontT42,tXc1,text,0); diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/t7.c --- a/Discovery/Src/t7.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/t7.c Tue Dec 14 15:36:10 2021 +0100 @@ -35,6 +35,7 @@ #include "gfx_fonts.h" #include "logbook_miniLive.h" #include "math.h" +#include "tComm.h" #include "tHome.h" #include "simulation.h" #include "timer.h" @@ -743,8 +744,11 @@ } else */ - if(DataEX_was_power_on()) + if(DataEX_was_power_on()) { GFX_write_string_color(&FontT42,&t7surfaceR,"cold start",4,CLUT_WarningRed); + // Reset the bluetooth interface after a cold start + tComm_Set_Bluetooth_Name(1); + } /* time and date */ translateDate(stateUsed->lifeData.dateBinaryFormat, &Sdate); @@ -1015,7 +1019,7 @@ else { textIdx = 0; - if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR) + if(isLoopMode(stateUsed->diveSettings.diveMode)) gasOffset = NUM_OFFSET_DILUENT; else gasOffset = 0; @@ -1090,6 +1094,9 @@ case DIVEMODE_CCR: GFX_write_string(&FontT24, &t7c1, "\f\002" "CCR", 0); break; + case DIVEMODE_PSCR: + GFX_write_string(&FontT24, &t7c1, "\f\002" "PSCR", 0); + break; case DIVEMODE_OC: GFX_write_string(&FontT24, &t7c1, "\f\002" "OC", 0); break; @@ -1610,7 +1617,8 @@ uint8_t t7_change_customview(uint8_t action) { uint8_t *pViews; - uint8_t *pStartView,*pCurView, *pLastView; + uint8_t *pStartView,*pLastView; + uint8_t *pCurView = NULL; _Bool cv_disabled = 0; if(stateUsed->mode == MODE_DIVE) @@ -1694,6 +1702,9 @@ char text[256]; char timeSuffix; uint8_t hoursToDisplay; +#ifdef ENABLE_PSCR_MODE + uint8_t showSimPPO2 = 1; +#endif uint16_t textpointer = 0; uint16_t heading = 0; int16_t start; @@ -1790,6 +1801,24 @@ } t7cC.WindowNumberOfTextLines = 3; } + else if(isSettingsWarning()) + { + if(warning_count_high_time) + { + shiftWindowY0 += 20; + t7cC.WindowY0 -= shiftWindowY0; + textpointer = 0; + text[textpointer++] = '\001'; + text[textpointer++] = TXT_2BYTE; + text[textpointer++] = TXT2BYTE_CheckSettings; + text[textpointer++] = '\n'; + text[textpointer++] = '\r'; + text[textpointer++] = 0; + GFX_write_string_color(&FontT42,&t7cC,text,1, CLUT_WarningRed); + t7cC.WindowY0 += shiftWindowY0; + } + t7cC.WindowNumberOfTextLines = 1; + } else // customtext { lineCountCustomtext = t7_customtextPrepare(text); @@ -1993,13 +2022,24 @@ { if((stateUsed->diveSettings.ppo2sensors_deactivated & (1<lifeData.ppO2Sensor_bar[i] == 0.0)) { - text[textpointer++] = '\031'; // labelcolor - text[textpointer++] = '\001'; - text[textpointer++] = '-'; - text[textpointer++] = '\n'; - text[textpointer++] = '\r'; - text[textpointer++] = '\030'; // main color - text[textpointer] = 0; +#ifdef ENABLE_PSCR_MODE + if((stateUsed->diveSettings.diveMode == DIVEMODE_PSCR) && (showSimPPO2) && (stateUsed->mode == MODE_DIVE)) /* display ppo2 sim in blue letters in case a slot is not used in the ppo2 custom view */ + { + text[textpointer++] = '\023'; + textpointer += snprintf(&text[textpointer],100,"\001%01.2f\n\r\030",stateUsed->lifeData.ppo2Simulated_bar); + showSimPPO2 = 0; + } + else +#endif + { + text[textpointer++] = '\031'; // labelcolor + text[textpointer++] = '\001'; + text[textpointer++] = '-'; + text[textpointer++] = '\n'; + text[textpointer++] = '\r'; + text[textpointer++] = '\030'; // main color + text[textpointer] = 0; + } } else { @@ -2515,9 +2555,10 @@ if(stateUsed->diveSettings.ccrOption) { - if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR) + if(isLoopMode(stateUsed->diveSettings.diveMode)) { snprintf(TextC2,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2); + if(stateUsed->warnings.betterSetpoint && warning_count_high_time && (stateUsed->diveSettings.diveMode == DIVEMODE_CCR)) { TextC2[0] = '\a'; // inverse instead of color \020 @@ -2547,7 +2588,7 @@ TextC2[1] = TXT_2BYTE; TextC2[2] = TXT2BYTE_WarnCnsHigh; TextC2[3] = 0; - GFX_write_string_color(&FontT48,&t7c1,TextC2,0,CLUT_WarningRed); + GFX_write_string_color(&FontT42,&t7c1,TextC2,0,CLUT_WarningRed); } else { @@ -2568,6 +2609,9 @@ GFX_write_string(&FontT24,&t7c1,"\027\f\002" "CCR",0); // GFX_write_string(&FontT24,&t7c1,"\f\177\177\x80" "CCR",0); else + if(stateUsed->diveSettings.diveMode == DIVEMODE_PSCR) + GFX_write_string(&FontT24,&t7c1,"\027\f\002" "PSCR",0); + else if(stateUsed->diveSettings.ccrOption) GFX_write_string(&FontT24,&t7c1,"\f\002\024" "Bailout",0); // GFX_write_string(&FontT24,&t7c1,"\f\177\177\x80\024" "Bailout",0); @@ -2661,11 +2705,16 @@ { selection_custom_field++; } - if((selection_custom_field == LLC_ScrubberTime) && ((settingsGetPointer()->scrubTimerMode == SCRUB_TIMER_OFF) || (settingsGetPointer()->dive_mode != DIVEMODE_CCR))) + if((selection_custom_field == LLC_ScrubberTime) && ((settingsGetPointer()->scrubTimerMode == SCRUB_TIMER_OFF) || (!isLoopMode(settingsGetPointer()->dive_mode)))) { selection_custom_field++; } - +#ifdef ENABLE_PSCR_MODE + if((selection_custom_field == LCC_SimPpo2) && (settingsGetPointer()->dive_mode != DIVEMODE_PSCR)) + { + selection_custom_field++; + } +#endif if(selection_custom_field >= LLC_END) { selection_custom_field = LLC_Empty; @@ -2803,6 +2852,12 @@ snprintf(text,TEXTSIZE,"\020%u\016\016%%\017", (settingsGetPointer()->scrubTimerCur * 100 / settingsGetPointer()->scrubTimerMax)); } break; +#ifdef ENABLE_PSCR_MODE + case LCC_SimPpo2: + headerText[2] = TXT_SimPpo2; + snprintf(text,TEXTSIZE,"\020%.2f\016\016Bar\017",stateUsed->lifeData.ppo2Simulated_bar); + break; +#endif #ifdef ENABLE_BOTTLE_SENSOR case LCC_BottleBar: @@ -3380,7 +3435,7 @@ text[textpointer++] = TXT_FutureTTS; text[textpointer++] = '\n'; text[textpointer++] = '\r'; - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (pSettings->dive_mode == DIVEMODE_CCR)) + if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode))) { text[textpointer++] = TXT_ScrubTime; @@ -3429,7 +3484,7 @@ else textpointer += snprintf(&text[textpointer],10,"\020%ih", (pDecoinfoFuture->output_time_to_surface_seconds + 59) / 3600); - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (pSettings->dive_mode == DIVEMODE_CCR)) + if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode))) { text[textpointer++] = '\n'; text[textpointer++] = '\r'; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tCCR.c --- a/Discovery/Src/tCCR.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tCCR.c Tue Dec 14 15:36:10 2021 +0100 @@ -65,6 +65,13 @@ #define BOTTLE_SENSOR_TIMEOUT (6000u) /* signal pressure budget as not received after 10 minutes (6000 * 100ms) */ #define MAX_SENSOR_COMPARE_DEVIATION (0.15f) /* max deviation between two sensors allowed before their results are rated as suspect */ +#define MAX_SENSOR_VOLTAGE_MV (250u) /* max allowed voltage value for a sensor measurement */ + +#ifdef ENABLE_ALTERNATIVE_SENSORTYP +#define MIN_SENSOR_VOLTAGE_MV (3u) /* min allowed voltage value for a sensor measurement (Inspiration, Submatix, Sentinel Typ) */ +#else +#define MIN_SENSOR_VOLTAGE_MV (8u) /* min allowed voltage value for a sensor measurement (legacy OSTC TYP) */ +#endif /* Private variables ---------------------------------------------------------*/ static SIrLink receiveHUD[2]; @@ -173,8 +180,8 @@ if(sensorActive[i]) { - if( (stateUsed->lifeData.sensorVoltage_mV[i] < 8) || - (stateUsed->lifeData.sensorVoltage_mV[i] > 250)) + if( (stateUsed->lifeData.sensorVoltage_mV[i] < MIN_SENSOR_VOLTAGE_MV) || + (stateUsed->lifeData.sensorVoltage_mV[i] > MAX_SENSOR_VOLTAGE_MV)) { sensorActive[i] = 0; switch(i) @@ -330,7 +337,7 @@ } /* decrease scrubber timer only in real dive mode */ - if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (pSettings->dive_mode == DIVEMODE_CCR) && (stateUsed->mode == MODE_DIVE) && (stateUsed == stateRealGetPointer())) + if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (stateUsed->mode == MODE_DIVE) && (stateUsed == stateRealGetPointer())) { ScrubberTimeoutCount++; if(ScrubberTimeoutCount >= 600) /* resolution is minutes */ @@ -444,18 +451,25 @@ static uint8_t tCCR_fallbackToFixedSetpoint(void) { uint8_t retVal = 0; - if((stateUsed->mode == MODE_DIVE) && (stateUsed->diveSettings.diveMode == DIVEMODE_CCR) && (stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) && (stateUsed->diveSettings.fallbackOption)) - { - uint8_t setpointCbar, actualGasID; + uint8_t setpointCbar, actualGasID; - setpointCbar = stateUsed->diveSettings.setpoint[1].setpoint_cbar; - stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; + if((stateUsed->mode == MODE_DIVE) && (stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) && (stateUsed->diveSettings.fallbackOption)) + { + if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR) + { + setpointCbar = stateUsed->diveSettings.setpoint[1].setpoint_cbar; + stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; + } + else + { + setpointCbar = stateUsed->lifeData.ppo2Simulated_bar * 100; + stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Simulation; + } + actualGasID = stateUsed->lifeData.actualGas.GasIdInSettings; + setActualGas_DM(&stateUsedWrite->lifeData,actualGasID,setpointCbar); - actualGasID = stateUsed->lifeData.actualGas.GasIdInSettings; - setActualGas_DM(&stateUsedWrite->lifeData,actualGasID,setpointCbar); - - set_warning_fallback(); - retVal = stateUsed->diveSettings.setpoint[1].setpoint_cbar; + set_warning_fallback(); + retVal = setpointCbar; } return retVal; } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenu.c --- a/Discovery/Src/tMenu.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenu.c Tue Dec 14 15:36:10 2021 +0100 @@ -58,6 +58,8 @@ #define MENU_WDW_HIGH 390 #define KEY_LABEL_HIGH 25 /* Height of the label used for the the user keys */ +#define SLOW_UPDATE_CNT 10 /* Some content shall not be update in short intervals => add prescalar */ + typedef struct { uint32_t StartAddressForPage[MAXPAGES+1]; @@ -530,7 +532,7 @@ tM_add(StMDECOP); // } - if((pSettings->dive_mode == DIVEMODE_CCR) || (stateUsed->diveSettings.ccrOption == 1)) + if((isLoopMode(pSettings->dive_mode)) || (stateUsed->diveSettings.ccrOption == 1)) { tM_add(StMCG); tM_add(StMSP); @@ -586,23 +588,45 @@ void tM_refresh_live_content(void) { + static uint8_t slowUpdate = SLOW_UPDATE_CNT; uint8_t page = 0; char text[MAX_PAGE_TEXTSIZE]; char subtext[MAX_PAGE_TEXTSIZE]; uint16_t tabPosition; - if((get_globalState() == StMSYS) && (actual_menu_content == MENU_SURFACE)) + uint32_t globalState = get_globalState(); + + slowUpdate--; + page = menu.pageMemoryForNavigation; + switch(globalState) { - page = menu.pageMemoryForNavigation; - tMSystem_refresh(0, text, &tabPosition, subtext); - update_content_with_new_frame(page, text, tabPosition, subtext); + case StMSYS: if(actual_menu_content == MENU_SURFACE) + { + tMSystem_refresh(0, text, &tabPosition, subtext); + update_content_with_new_frame(page, text, tabPosition, subtext); + } + break; + case StMHARD: tMHardware_refresh(0, text, &tabPosition, subtext); + update_content_with_new_frame(page, text, tabPosition, subtext); + break; + case StMOG: if((actual_menu_content != MENU_SURFACE) && (slowUpdate == 0)) + { + tMOG_refresh(0, text, &tabPosition, subtext); + update_content_with_new_frame(page, text, tabPosition, subtext); + } + break; + case StMCG: if((actual_menu_content != MENU_SURFACE) && (slowUpdate == 0)) + { + tMCG_refresh(0, text, &tabPosition, subtext); + update_content_with_new_frame(page, text, tabPosition, subtext); + } + break; + default: + break; } - else - if(get_globalState() == StMHARD) + if(slowUpdate == 0) { - page = menu.pageMemoryForNavigation; - tMHardware_refresh(0, text, &tabPosition, subtext); - update_content_with_new_frame(page, text, tabPosition, subtext); + slowUpdate = SLOW_UPDATE_CNT; } tMscreen.FBStartAdress = menu.StartAddressForPage[page]; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuDeco.c --- a/Discovery/Src/tMenuDeco.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuDeco.c Tue Dec 14 15:36:10 2021 +0100 @@ -67,6 +67,9 @@ case DIVEMODE_Apnea: divemode = TXT_Apnoe; break; + case DIVEMODE_PSCR: + divemode = TXT_PSClosedCircuit; + break; default : divemode = TXT_OpenCircuit; break; @@ -81,14 +84,22 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; - if(data->dive_mode == DIVEMODE_CCR) + if(isLoopMode(data->dive_mode)) { if((line == 0) || (line == 2)) { - if(data->CCR_Mode == CCRMODE_Sensors) - CcrModusTxtId = TXT_Sensor; - else - CcrModusTxtId = TXT_FixedSP; + switch(data->CCR_Mode) + { + case CCRMODE_Sensors: CcrModusTxtId = TXT_Sensor; + break; + case CCRMODE_FixedSetpoint: CcrModusTxtId = TXT_FixedSP; + break; + case CCRMODE_Simulation: CcrModusTxtId = TXT_SimPpo2; + break; + default: CcrModusTxtId = 'X'; + break; + } + textPointer += snprintf(&text[textPointer], 60,\ "%c" diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEdit.c --- a/Discovery/Src/tMenuEdit.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEdit.c Tue Dec 14 15:36:10 2021 +0100 @@ -213,6 +213,13 @@ break; case (StMXTRA_CompassHeading & MaskFieldDigit): refreshFct = refresh_CompassHeading; break; + case (StMXTRA_PSCR_O2_Drop & MaskFieldDigit): if(settingsGetPointer()->dive_mode != DIVEMODE_PSCR) /* workaround because PSCR mode is set dynamic */ + { + refreshFct = refresh_CO2Data; + } + break; + case (StMXTRA_CO2_Sensor & MaskFieldDigit): refreshFct = refresh_CO2Data; + break; case (StMSYS4_Info & MaskFieldDigit): refreshFct = &refresh_InformationPage; break; case (StMPLAN5_ExitResult & MaskFieldDigit): refreshFct = refresh_PlanResult; @@ -256,6 +263,7 @@ { if(WriteSettings) { + reset_SettingWarning(); GFX_logoAutoOff(); ext_flash_write_settings(0); WriteSettings = 0; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditCustom.c --- a/Discovery/Src/tMenuEditCustom.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditCustom.c Tue Dec 14 15:36:10 2021 +0100 @@ -169,6 +169,12 @@ text[4] = TXT_AtemGasVorrat; break; #endif + +#ifdef ENABLE_PSCR_MODE + case LCC_SimPpo2: + text[4] = TXT_SimPpo2; + break; +#endif /* none */ case LLC_Empty: text[4] = '-'; @@ -713,7 +719,7 @@ uint8_t OnAction_CViewPortLayout(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) { SSettings* pSettings = settingsGetPointer(); - if((pSettings->viewPortMode >> 4) & 0x10 != 0) + if(((pSettings->viewPortMode >> 4) & 0x10) != 0) { pSettings->viewPortMode &= 0xEF; /* 1110 1111 */ } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditDeco.c --- a/Discovery/Src/tMenuEditDeco.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditDeco.c Tue Dec 14 15:36:10 2021 +0100 @@ -32,6 +32,7 @@ #include "gfx_fonts.h" #include "tMenuEdit.h" #include "unit.h" +#include "configuration.h" /* Private variables ---------------------------------------------------------*/ static uint8_t lineSelected = 0; @@ -46,11 +47,7 @@ static void openEdit_Salinity(void); /* Announced function prototypes -----------------------------------------------*/ - -static uint8_t OnAction_OC (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); -static uint8_t OnAction_CC (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); -static uint8_t OnAction_Apnea (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); -static uint8_t OnAction_Gauge (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +static uint8_t OnAction_setMode (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_FutureTTS (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_ppO2Max (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_SafetyStop (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); @@ -66,7 +63,7 @@ lineSelected = line; - if((data->dive_mode != DIVEMODE_CCR )&& (line > 1)) + if((!isLoopMode(data->dive_mode)) && (line > 1)) line += 1; switch(line) @@ -101,6 +98,7 @@ #define APNEAANDGAUGE char text[32]; + uint8_t lineOffset = 0; uint8_t actualDiveMode, active; SSettings *pSettings = settingsGetPointer(); actualDiveMode = pSettings->dive_mode; @@ -113,6 +111,10 @@ text[1] = 0; +#ifdef ENABLE_PSCR_MODE + lineOffset = ME_Y_LINE_STEP; +#endif + text[0] = TXT_OpenCircuit; if(actualDiveMode == DIVEMODE_OC) active = 1; @@ -127,89 +129,81 @@ active = 0; write_field_on_off(StMDECO1_CC, 30, 500, ME_Y_LINE2, &FontT48, text, active); - #ifdef APNEAANDGAUGE +#ifdef ENABLE_PSCR_MODE + text[0] = TXT_PSClosedCircuit; + if(actualDiveMode == DIVEMODE_PSCR) + active = 1; + else + active = 0; + write_field_on_off(StMDECO1_PSCR, 30, 500, ME_Y_LINE3, &FontT48, text, active); +#endif +#ifdef APNEAANDGAUGE text[0] = TXT_Apnoe; if(actualDiveMode == DIVEMODE_Apnea) active = 1; else active = 0; - write_field_on_off(StMDECO1_Apnea, 30, 500, ME_Y_LINE3, &FontT48, text, active); + write_field_on_off(StMDECO1_Apnea, 30, 500, ME_Y_LINE3 + lineOffset, &FontT48, text, active); text[0] = TXT_Gauge; if(actualDiveMode == DIVEMODE_Gauge) active = 1; else active = 0; - write_field_on_off(StMDECO1_Gauge, 30, 500, ME_Y_LINE4, &FontT48, text, active); - #endif + write_field_on_off(StMDECO1_Gauge, 30, 500, ME_Y_LINE4 + lineOffset, &FontT48, text, active); +#endif - setEvent(StMDECO1_OC, (uint32_t)OnAction_OC); - setEvent(StMDECO1_CC, (uint32_t)OnAction_CC); - #ifdef APNEAANDGAUGE - setEvent(StMDECO1_Apnea, (uint32_t)OnAction_Apnea); - setEvent(StMDECO1_Gauge, (uint32_t)OnAction_Gauge); - #endif + setEvent(StMDECO1_OC, (uint32_t)OnAction_setMode); + setEvent(StMDECO1_CC, (uint32_t)OnAction_setMode); +#ifdef ENABLE_PSCR_MODE + setEvent(StMDECO1_PSCR, (uint32_t)OnAction_setMode); +#endif + +#ifdef APNEAANDGAUGE + setEvent(StMDECO1_Apnea, (uint32_t)OnAction_setMode); + setEvent(StMDECO1_Gauge, (uint32_t)OnAction_setMode); +#endif write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext); } -static uint8_t OnAction_OC (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) + +static uint8_t OnAction_setMode (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) //(uint32_t newMode) { - SSettings *pSettings = settingsGetPointer(); - if(pSettings->dive_mode == DIVEMODE_OC) - return EXIT_TO_MENU; - pSettings->dive_mode = DIVEMODE_OC; - setActualGasFirst(&stateRealGetPointerWrite()->lifeData); - tMenuEdit_set_on_off(editId, 1); - tMenuEdit_set_on_off(StMDECO1_CC, 0); - tMenuEdit_set_on_off(StMDECO1_Apnea, 0); - tMenuEdit_set_on_off(StMDECO1_Gauge, 0); - return UPDATE_DIVESETTINGS; -} + uint32_t modeArray[] = {StMDECO1_OC, StMDECO1_CC, StMDECO1_Gauge, StMDECO1_Apnea /* definition needs to follow order of DIVEMODE (settings.h) */ +#ifdef ENABLE_PSCR_MODE + , StMDECO1_PSCR +#endif + }; + + uint8_t index = 0; + SSettings *pSettings = settingsGetPointer(); + uint8_t retVal = EXIT_TO_MENU; + uint8_t lastMode = pSettings->dive_mode; -static uint8_t OnAction_CC (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) -{ - SSettings *pSettings = settingsGetPointer(); - if(pSettings->dive_mode == DIVEMODE_CCR) - return EXIT_TO_MENU; - pSettings->dive_mode = DIVEMODE_CCR; - setActualGasFirst(&stateRealGetPointerWrite()->lifeData); - tMenuEdit_set_on_off(editId, 1); - tMenuEdit_set_on_off(StMDECO1_OC, 0); - tMenuEdit_set_on_off(StMDECO1_Apnea, 0); - tMenuEdit_set_on_off(StMDECO1_Gauge, 0); - return UPDATE_DIVESETTINGS; -} - - -static uint8_t OnAction_Apnea (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) -{ - SSettings *pSettings = settingsGetPointer(); - if(pSettings->dive_mode == DIVEMODE_Apnea) - return EXIT_TO_MENU; - pSettings->dive_mode = DIVEMODE_Apnea; - setActualGasFirst(&stateRealGetPointerWrite()->lifeData); - tMenuEdit_set_on_off(editId, 1); - tMenuEdit_set_on_off(StMDECO1_CC, 0); - tMenuEdit_set_on_off(StMDECO1_OC, 0); - tMenuEdit_set_on_off(StMDECO1_Gauge, 0); - return UPDATE_DIVESETTINGS; -} - - -static uint8_t OnAction_Gauge (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) -{ - SSettings *pSettings = settingsGetPointer(); - if(pSettings->dive_mode == DIVEMODE_Gauge) - return EXIT_TO_MENU; - pSettings->dive_mode = DIVEMODE_Gauge; - setActualGasFirst(&stateRealGetPointerWrite()->lifeData); - tMenuEdit_set_on_off(editId, 1); - tMenuEdit_set_on_off(StMDECO1_CC, 0); - tMenuEdit_set_on_off(StMDECO1_Apnea, 0); - tMenuEdit_set_on_off(StMDECO1_OC, 0); - return UPDATE_DIVESETTINGS; + setActualGasFirst(&stateRealGetPointerWrite()->lifeData); + while(index < sizeof(modeArray) / 4) /* calculate number of items out of array size (bytes) */ + { + if(editId == modeArray[index]) + { + if(pSettings->dive_mode != index) + { + tMenuEdit_set_on_off(modeArray[index], 1); + pSettings->dive_mode = index; + retVal = UPDATE_DIVESETTINGS; + } + } + else + { + if(lastMode == index) /* reset state of previous mode selection */ + { + tMenuEdit_set_on_off(modeArray[index], 0); + } + } + index++; + } + return retVal; } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditGasOC.c --- a/Discovery/Src/tMenuEditGasOC.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditGasOC.c Tue Dec 14 15:36:10 2021 +0100 @@ -92,7 +92,7 @@ { if(line == 6) { - if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) || (stateUsed->diveSettings.ccrOption == 1)) + if(isLoopMode(settingsGetPointer()->dive_mode) || (stateUsed->diveSettings.ccrOption == 1)) { selectPage(StMOG); } @@ -122,7 +122,7 @@ { if(line == 6) { - if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) || (stateUsed->diveSettings.ccrOption == 1)) + if(isLoopMode(settingsGetPointer()->dive_mode) || (stateUsed->diveSettings.ccrOption == 1)) { selectPage(StMCG); } @@ -367,7 +367,7 @@ void tMEGas_check_switch_to_bailout(void) { - if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR) + if(isLoopMode(stateUsed->diveSettings.diveMode)) { stateUsedWrite->diveSettings.diveMode = DIVEMODE_OC; block_diluent_page(); diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditPlanner.c --- a/Discovery/Src/tMenuEditPlanner.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditPlanner.c Tue Dec 14 15:36:10 2021 +0100 @@ -689,7 +689,7 @@ textpointer += snprintf(&text[textpointer],20,"GF %u/%u", stateUsed->diveSettings.gf_low, stateUsed->diveSettings.gf_high); break; case 1: - if(settingsGetPointer()->dive_mode == DIVEMODE_CCR) + if(isLoopMode(settingsGetPointer()->dive_mode)) text[textpointer++] = 'C'; else text[textpointer++] = 'O'; diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditSetpoint.c --- a/Discovery/Src/tMenuEditSetpoint.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditSetpoint.c Tue Dec 14 15:36:10 2021 +0100 @@ -58,6 +58,8 @@ void openEdit_Setpoint(uint8_t line) { uint8_t useSensorSubMenu = 0; + char text[20]; + uint8_t sensorActive[3]; /* dive mode */ if(actual_menu_content != MENU_SURFACE) @@ -66,7 +68,7 @@ setpointCbar = 100; // actualGasID - if(stateUsedWrite->diveSettings.diveMode != DIVEMODE_CCR) + if(!isLoopMode(stateUsedWrite->diveSettings.diveMode)) { actualGasID = stateUsedWrite->lifeData.lastDiluent_GasIdInSettings; if((actualGasID <= NUM_OFFSET_DILUENT) || (actualGasID > NUM_GASES + NUM_OFFSET_DILUENT)) @@ -76,7 +78,7 @@ actualGasID = stateUsedWrite->lifeData.actualGas.GasIdInSettings; // setpointCbar, CCR_Mode and sensor menu - if(line < 6) + if((line < 6) && (stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR)) /* setpoints inactive in PSCR mode */ { setpointCbar = stateUsedWrite->diveSettings.setpoint[line].setpoint_cbar; stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; @@ -96,25 +98,32 @@ stateUsedWrite->diveSettings.setpoint[line].note.ub.first = 1; } } - else + else /* menu item not pointing to setpoint selection => use sensor or ppo2 simulation */ { - if(stateUsedWrite->diveSettings.CCR_Mode != CCRMODE_Sensors) - { - /* setpoint_cbar will be written by updateSetpointStateUsed() in main.c loop */ - setpointCbar = 255; - stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Sensors; - } - else - { - useSensorSubMenu = 1; - } + if((stateUsedWrite->diveSettings.diveMode == DIVEMODE_PSCR) && (line == 2)) + { + stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Simulation; + } + else /* => use sensor */ + { + if(stateUsedWrite->diveSettings.CCR_Mode != CCRMODE_Sensors) + { + /* setpoint_cbar will be written by updateSetpointStateUsed() in main.c loop */ + setpointCbar = 255; + stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Sensors; + } + else + { + useSensorSubMenu = 1; + } + } } setActualGas_DM(&stateUsedWrite->lifeData,actualGasID,setpointCbar); - if(stateUsedWrite->diveSettings.diveMode != DIVEMODE_CCR) + if(!isLoopMode(stateUsedWrite->diveSettings.diveMode)) { - stateUsedWrite->diveSettings.diveMode = DIVEMODE_CCR; + stateUsedWrite->diveSettings.diveMode = settingsGetPointer()->dive_mode; unblock_diluent_page(); } @@ -129,9 +138,6 @@ set_globalState_Menu_Line(line); resetMenuEdit(CLUT_MenuPageGasSP); - char text[20]; - uint8_t sensorActive[3]; - text[0] = '\001'; text[1] = TXT_o2Sensors; text[2] = 0; @@ -145,6 +151,7 @@ else { snprintf (text,20,"Sensor 1 (%01.2f)", stateUsed->lifeData.ppO2Sensor_bar[0] ); + sensorActive[0] = 1; } write_label_var( 96, 600, ME_Y_LINE1, &FontT48, text); if(stateUsedWrite->diveSettings.ppo2sensors_deactivated & 2) @@ -155,6 +162,7 @@ else { snprintf (text,20,"Sensor 2 (%01.2f)", stateUsed->lifeData.ppO2Sensor_bar[1] ); + sensorActive[1] = 1; } write_label_var( 96, 600, ME_Y_LINE2, &FontT48, text); if(stateUsedWrite->diveSettings.ppo2sensors_deactivated & 4) @@ -165,13 +173,10 @@ else { snprintf (text,20,"Sensor 3 (%01.2f)", stateUsed->lifeData.ppO2Sensor_bar[2] ); + sensorActive[2] = 1; } write_label_var( 96, 600, ME_Y_LINE3, &FontT48, text); - sensorActive[0] = 1; - sensorActive[1] = 1; - sensorActive[2] = 1; - write_field_on_off(StMSP_Sensor1, 30, 95, ME_Y_LINE1, &FontT48, "", sensorActive[0]); write_field_on_off(StMSP_Sensor2, 30, 95, ME_Y_LINE2, &FontT48, "", sensorActive[1]); write_field_on_off(StMSP_Sensor3, 30, 95, ME_Y_LINE3, &FontT48, "", sensorActive[2]); @@ -329,23 +334,26 @@ uint8_t spId; uint8_t depth; - spId = actualBetterSetpointId(); - - depth = stateUsedWrite->diveSettings.setpoint[spId].depth_meter; - - // BetterSetpoint warning only once -> clear active - for(int i=0; i<=NUM_GASES; i++) + if(stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR) /* no setpoints in PSCR mode */ { - stateUsedWrite->diveSettings.setpoint[i].note.ub.first = 0; - if(stateUsedWrite->diveSettings.setpoint[i].depth_meter <= depth) - stateUsedWrite->diveSettings.setpoint[i].note.ub.active = 0; - } + spId = actualBetterSetpointId(); + + depth = stateUsedWrite->diveSettings.setpoint[spId].depth_meter; - // new setpoint - stateUsedWrite->diveSettings.setpoint[spId].note.ub.first = 1; + // BetterSetpoint warning only once -> clear active + for(int i=0; i<=NUM_GASES; i++) + { + stateUsedWrite->diveSettings.setpoint[i].note.ub.first = 0; + if(stateUsedWrite->diveSettings.setpoint[i].depth_meter <= depth) + stateUsedWrite->diveSettings.setpoint[i].note.ub.active = 0; + } - // change in lifeData - setActualGas_DM(&stateUsedWrite->lifeData, stateUsedWrite->lifeData.actualGas.GasIdInSettings, stateUsedWrite->diveSettings.setpoint[spId].setpoint_cbar); + // new setpoint + stateUsedWrite->diveSettings.setpoint[spId].note.ub.first = 1; + + // change in lifeData + setActualGas_DM(&stateUsedWrite->lifeData, stateUsedWrite->lifeData.actualGas.GasIdInSettings, stateUsedWrite->diveSettings.setpoint[spId].setpoint_cbar); + } } static uint8_t OnAction_SP_DM_Sensor1 (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditSystem.c --- a/Discovery/Src/tMenuEditSystem.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditSystem.c Tue Dec 14 15:36:10 2021 +0100 @@ -34,6 +34,7 @@ #include "gfx_fonts.h" #include "ostc.h" #include "settings.h" // for getLicence() +#include "tComm.h" #include "tHome.h" // for enum CUSTOMVIEWS and init_t7_compass() #include "tMenu.h" #include "tMenuEdit.h" @@ -86,6 +87,7 @@ uint8_t OnAction_Nothing (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); 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_ResetBluetooth(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); @@ -1073,11 +1075,16 @@ text[2] = 0; write_field_button(StMSYS5_SetFactoryBC, 30, 800, ME_Y_LINE2, &FontT48, text); + text[0] = TXT_2BYTE; + text[1] = TXT2BYTE_ResetBluetooth; + text[2] = 0; + write_field_button(StMSYS5_ResetBluetooth, 30, 800, ME_Y_LINE3, &FontT48, text); + #ifdef ENABLE_ANALYSE_SAMPLES text[0] = TXT_2BYTE; text[1] = TXT2BYTE_SetSampleIndex; text[2] = 0; - write_field_button(StMSYS5_SetSampleIndx, 30, 800, ME_Y_LINE3, &FontT48, text); + write_field_button(StMSYS5_SetSampleIndx, 30, 800, ME_Y_LINE4, &FontT48, text); #endif @@ -1095,6 +1102,7 @@ setEvent(StMSYS5_Exit, (uint32_t)OnAction_Exit); setEvent(StMSYS5_SetFactoryBC, (uint32_t)OnAction_SetFactoryDefaults); + setEvent(StMSYS5_ResetBluetooth, (uint32_t)OnAction_ResetBluetooth); #ifdef ENABLE_ANALYSE_SAMPLES setEvent(StMSYS5_SetSampleIndx, (uint32_t)OnAction_RecoverSampleIdx); #endif @@ -1104,6 +1112,7 @@ { setEvent(StMSYS5_Exit, (uint32_t)OnAction_Exit); setEvent(StMSYS5_SetFactoryBC, (uint32_t)OnAction_SetFactoryDefaults); + setEvent(StMSYS5_ResetBluetooth, (uint32_t)OnAction_ResetBluetooth); #ifdef ENABLE_ANALYSE_SAMPLES setEvent(StMSYS5_SetSampleIndx, (uint32_t)OnAction_RecoverSampleIdx); #endif @@ -1224,6 +1233,13 @@ return EXIT_TO_MENU; } +uint8_t OnAction_ResetBluetooth(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + tComm_Set_Bluetooth_Name(1); + + 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) { diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuEditXtra.c --- a/Discovery/Src/tMenuEditXtra.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuEditXtra.c Tue Dec 14 15:36:10 2021 +0100 @@ -35,6 +35,7 @@ #include "tMenuEdit.h" #include "data_exchange_main.h" #include "motion.h" +#include "configuration.h" /* Private function prototypes -----------------------------------------------*/ @@ -47,10 +48,26 @@ static void openEdit_ScrubberTimer(uint8_t line); static void openEdit_ScrubberReset(void); static void openEdit_ScrubberTimerMode(void); +#ifdef ENABLE_PSCR_MODE +static void openEdit_PSCRO2Drop(uint8_t line); +static void openEdit_PSCRLungRatio(uint8_t line); +#endif +#ifdef ENABLE_CO2_SUPPORT +static void openEdit_CO2Sensor(void); +#endif /* Announced function prototypes -----------------------------------------------*/ uint8_t OnAction_CompassHeading (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_ScrubberTimer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#ifdef ENABLE_PSCR_MODE +static uint8_t OnAction_PSCRO2Drop(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +static uint8_t OnAction_PSCRLungRation(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#endif + +#ifdef ENABLE_CO2_SUPPORT +static uint8_t OnAction_CO2OnOff(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +static uint8_t OnAction_CO2Calib(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#endif /* Exported functions --------------------------------------------------------*/ @@ -91,6 +108,11 @@ } else /* surface mode */ { + if((settingsGetPointer()->dive_mode != DIVEMODE_PSCR) && (line > 3)) /* PSCR items are only optional */ + { + line = 6; + } + switch(line) { case 1: openEdit_ScrubberTimer(line); @@ -99,6 +121,16 @@ break; case 3: openEdit_ScrubberTimerMode(); break; +#ifdef ENABLE_PSCR_MODE + case 4: openEdit_PSCRO2Drop(line); + break; + case 5: openEdit_PSCRLungRatio(line); + break; +#endif +#ifdef ENABLE_CO2_SUPPORT + case 6: openEdit_CO2Sensor(); + break; +#endif default: break; } @@ -191,6 +223,103 @@ exitMenuEdit_to_Menu_with_Menu_Update(); } +#ifdef ENABLE_PSCR_MODE +static void openEdit_PSCRO2Drop(uint8_t line) +{ + uint8_t localO2Drop; + uint16_t y_line; + + char text[32]; + SSettings *pSettings = settingsGetPointer(); + localO2Drop = pSettings->pscr_o2_drop; + + y_line = ME_Y_LINE_BASE + (line * ME_Y_LINE_STEP); + + text[0] = '\001'; + text[1] = TXT_PSCRO2Drop; + text[2] = 0; + write_topline(text); + + text[0] = '\002'; + text[1] = '\016'; + text[2] = '\016'; + text[3] = '%'; + text[4] = 0; + write_label_fix( 20, 800, y_line, &FontT48, TXT_PSCRO2Drop); + write_label_var( 435, 780, y_line, &FontT48, text); + write_field_udigit(StMXTRA_PSCR_O2_Drop, 710, 779, y_line, &FontT48, "##", (uint32_t)localO2Drop, 0, 0, 0); + + write_buttonTextline(TXT2BYTE_ButtonMinus,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonPlus); + + setEvent(StMXTRA_PSCR_O2_Drop, (uint32_t)OnAction_PSCRO2Drop); + startEdit(); +} + +static void openEdit_PSCRLungRatio(uint8_t line) +{ + uint8_t localLungRatio; + uint16_t y_line; + + char text[32]; + SSettings *pSettings = settingsGetPointer(); + localLungRatio = pSettings->pscr_lung_ratio; + + y_line = ME_Y_LINE_BASE + (line * ME_Y_LINE_STEP); + + text[0] = '\001'; + text[1] = TXT_PSCRO2Drop; + text[2] = 0; + write_topline(text); + + text[0] = '\002'; + text[1] = '1'; + text[2] = '/'; + text[3] = 0; + + write_label_fix( 20, 800, y_line, &FontT48, TXT_PSCRLungRatio); + write_label_var( 435, 710, y_line, &FontT48, text); + write_field_udigit(StMXTRA_PSCR_LUNG_RATIO, 710, 779, y_line, &FontT48, "##", (uint32_t)localLungRatio, 0, 0, 0); + + write_buttonTextline(TXT2BYTE_ButtonMinus,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonPlus); + + setEvent(StMXTRA_PSCR_LUNG_RATIO, (uint32_t)OnAction_PSCRLungRation); + startEdit(); +} +#endif + +#ifdef ENABLE_CO2_SUPPORT +static void openEdit_CO2Sensor() +{ + char text[32]; + snprintf(text,32,"\001%c",TXT_CO2Sensor); + write_topline(text); + + refresh_CO2Data(); + if(settingsGetPointer()->co2_sensor_active) + { + text[0] = '\005'; + } + else + { + text[0] = '\006'; + } + text[0] = TXT_CO2Sensor; + text[1] = 0; + + write_field_on_off(StMXTRA_CO2_Sensor, 30, 95, ME_Y_LINE3, &FontT48, text, settingsGetPointer()->co2_sensor_active); + + text[0] = TXT_2BYTE; + text[1] = TXT2BYTE_O2Calib; + text[2] = 0; + write_field_button(StMXTRA_CO2_Sensor_Calib,30, 800, ME_Y_LINE4, &FontT48, text); + + setEvent(StMXTRA_CO2_Sensor, (uint32_t)OnAction_CO2OnOff); + setEvent(StMXTRA_CO2_Sensor_Calib, (uint32_t)OnAction_CO2Calib); + + write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext); +} +#endif + void refresh_CompassHeading(void) { uint16_t heading; @@ -209,6 +338,23 @@ tMenuEdit_refresh_field(StMXTRA_CompassHeading); } +void refresh_CO2Data(void) +{ + char text[32]; + + snprintf(text,32,"\001%c",TXT_CO2Sensor); + write_topline(text); + + snprintf(text,32,"CO2: %d ppm",stateUsed->lifeData.CO2_data.CO2_ppm); + write_label_var( 30, 800, ME_Y_LINE1, &FontT48, text); + + snprintf(text,32,"Signal: %d",stateUsed->lifeData.CO2_data.signalStrength); + write_label_var( 30, 800, ME_Y_LINE2, &FontT48, text); + + tMenuEdit_refresh_field(StMXTRA_CO2_Sensor); + tMenuEdit_refresh_field(StMXTRA_CO2_Sensor_Calib); +} + void openEdit_CompassHeading(void) { @@ -267,4 +413,107 @@ } return digitContentNew; } +#ifdef ENABLE_PSCR_MODE +static uint8_t OnAction_PSCRO2Drop(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + SSettings *pSettings; + uint8_t digitContentNew = EXIT_TO_MENU; + uint32_t newO2Drop; + if(action == ACTION_BUTTON_ENTER) + { + return digitContent; + } + if(action == ACTION_BUTTON_ENTER_FINAL) + { + evaluateNewString(editId, &newO2Drop, 0, 0, 0); + + if(newO2Drop > PSCR_MAX_O2_DROP) + newO2Drop = PSCR_MAX_O2_DROP; + + pSettings = settingsGetPointer(); + pSettings->pscr_o2_drop = newO2Drop; + + tMenuEdit_newInput(editId, newO2Drop, 0, 0, 0); + digitContentNew = UPDATE_AND_EXIT_TO_MENU; + } + if(action == ACTION_BUTTON_NEXT) + { + digitContentNew = digitContent + 1; + if(digitContentNew > '9') + digitContentNew = '0'; + } + if(action == ACTION_BUTTON_BACK) + { + digitContentNew = digitContent - 1; + if(digitContentNew < '0') + digitContentNew = '9'; + } + return digitContentNew; +} + +static uint8_t OnAction_PSCRLungRation(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + SSettings *pSettings; + uint8_t digitContentNew = EXIT_TO_MENU; + uint32_t newLungRatio; + + if(action == ACTION_BUTTON_ENTER) + { + return digitContent; + } + if(action == ACTION_BUTTON_ENTER_FINAL) + { + evaluateNewString(editId, &newLungRatio, 0, 0, 0); + + if(newLungRatio > PSCR_MAX_LUNG_RATIO) + newLungRatio = PSCR_MAX_LUNG_RATIO; + + if(newLungRatio < PSCR_MIN_LUNG_RATIO) + newLungRatio = PSCR_MIN_LUNG_RATIO; + + pSettings = settingsGetPointer(); + pSettings->pscr_lung_ratio = newLungRatio; + + tMenuEdit_newInput(editId, newLungRatio, 0, 0, 0); + digitContentNew = UPDATE_AND_EXIT_TO_MENU; + } + if(action == ACTION_BUTTON_NEXT) + { + digitContentNew = digitContent + 1; + if(digitContentNew > '9') + digitContentNew = '0'; + } + if(action == ACTION_BUTTON_BACK) + { + digitContentNew = digitContent - 1; + if(digitContentNew < '0') + digitContentNew = '9'; + } + return digitContentNew; +} +#endif + +#ifdef ENABLE_CO2_SUPPORT +static uint8_t OnAction_CO2OnOff(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + SSettings *pSettings = settingsGetPointer(); + if(pSettings->co2_sensor_active) + { + pSettings->co2_sensor_active = 0; + tMenuEdit_set_on_off(StMXTRA_CO2_Sensor,0); + } + else + { + pSettings->co2_sensor_active = 1; + tMenuEdit_set_on_off(StMXTRA_CO2_Sensor,1); + } + return UPDATE_DIVESETTINGS; +} + +static uint8_t OnAction_CO2Calib(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + DataEX_setExtInterface_Cmd(EXT_INTERFACE_CO2_CALIB); + return UPDATE_DIVESETTINGS; +} +#endif diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuGas.c --- a/Discovery/Src/tMenuGas.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuGas.c Tue Dec 14 15:36:10 2021 +0100 @@ -55,7 +55,7 @@ } else { - if (stateUsed->diveSettings.diveMode == DIVEMODE_CCR) + if (isLoopMode(stateUsed->diveSettings.diveMode)) gas_mode = OCGAS_BAILOUT_INACTIVE; else gas_mode = OCGAS_BAILOUT_ACTIVE; @@ -328,7 +328,7 @@ text[textPointer++] = 0; } else /* switch to bailout selection in surface mode */ - if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) || (stateUsed->diveSettings.ccrOption == 1)) + if((isLoopMode(settingsGetPointer()->dive_mode)) || (stateUsed->diveSettings.ccrOption == 1)) { text[textPointer++] = '\024'; if(gasMode == CCGAS_STANDARD) diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuSetpoint.c --- a/Discovery/Src/tMenuSetpoint.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuSetpoint.c Tue Dec 14 15:36:10 2021 +0100 @@ -53,76 +53,79 @@ *tab = 130; *subtext = 0; - for(int spId=1;spId<=NUM_GASES;spId++) + if((actual_menu_content == MENU_SURFACE) || (stateUsed->diveSettings.diveMode != DIVEMODE_PSCR)) /* do not show setpoints in PSCR mode */ { - if(line && (line != spId)) - { - first = pSetpointLine[spId].note.ub.first; - if(first == 0) - { - strcpy(&text[textPointer], - "\t" - "\177" - "*" - "\n\r" - ); - textPointer += 5; - } - else - { - strcpy(&text[textPointer],"\n\r"); - textPointer += 2; - } - } - else - { - setpoint_cbar = pSetpointLine[spId].setpoint_cbar; - depthUp = pSetpointLine[spId].depth_meter; - //active = pSetpointLine[spId].note.ub.active; - first = pSetpointLine[spId].note.ub.first; + for(int spId=1;spId<=NUM_GASES;spId++) + { + if(line && (line != spId)) + { + first = pSetpointLine[spId].note.ub.first; + if(first == 0) + { + strcpy(&text[textPointer], + "\t" + "\177" + "*" + "\n\r" + ); + textPointer += 5; + } + else + { + strcpy(&text[textPointer],"\n\r"); + textPointer += 2; + } + } + else + { + setpoint_cbar = pSetpointLine[spId].setpoint_cbar; + depthUp = pSetpointLine[spId].depth_meter; + //active = pSetpointLine[spId].note.ub.active; + first = pSetpointLine[spId].note.ub.first; - strcpy(&text[textPointer],"\020"); // if(active) always active - textPointer += 1; + strcpy(&text[textPointer],"\020"); // if(active) always active + textPointer += 1; - sp_high = setpoint_cbar / 100; + sp_high = setpoint_cbar / 100; - text[textPointer++] = 'S'; - text[textPointer++] = 'P'; - text[textPointer++] = '0' + spId; - text[textPointer++] = '\t'; + text[textPointer++] = 'S'; + text[textPointer++] = 'P'; + text[textPointer++] = '0' + spId; + text[textPointer++] = '\t'; - if((first == 0) || (actual_menu_content != MENU_SURFACE)) - strcpy(&text[textPointer++],"\177"); + if((first == 0) || (actual_menu_content != MENU_SURFACE)) + strcpy(&text[textPointer++],"\177"); - char color = '\031'; - if(depthUp) - color = '\020'; + char color = '\031'; + if(depthUp) + color = '\020'; - textPointer += snprintf(&text[textPointer], 57, - "* " - "%u.%02u" - "\016\016" - " bar" - "\017" - "\034" - " " - "\016\016" - " " - "\017" - "%c" - "%3u" - "\016\016" - " %c%c" - "\017" - "\035" - "\n\r", - sp_high, setpoint_cbar - (100 * sp_high), - color, - unit_depth_integer(depthUp), - unit_depth_char1(), - unit_depth_char2() - ); - } + textPointer += snprintf(&text[textPointer], 57, + "* " + "%u.%02u" + "\016\016" + " bar" + "\017" + "\034" + " " + "\016\016" + " " + "\017" + "%c" + "%3u" + "\016\016" + " %c%c" + "\017" + "\035" + "\n\r", + sp_high, setpoint_cbar - (100 * sp_high), + color, + unit_depth_integer(depthUp), + unit_depth_char1(), + unit_depth_char2() + ); + } + } } if((actual_menu_content != MENU_SURFACE) /*&& (line == 0)*/) { @@ -131,6 +134,12 @@ text[textPointer++] = TXT2BYTE_UseSensor; text[textPointer++] = '\n'; text[textPointer++] = '\r'; + + + if(stateUsed->diveSettings.diveMode == DIVEMODE_PSCR) + { + textPointer += snprintf(&text[textPointer], 20,"\020%c", TXT_SimPpo2); + } text[textPointer++] = 0; } else diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/tMenuXtra.c --- a/Discovery/Src/tMenuXtra.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/tMenuXtra.c Tue Dec 14 15:36:10 2021 +0100 @@ -47,6 +47,8 @@ *tab = 500; *subtext = 0; + SSettings *pSettings = settingsGetPointer(); + /* DIVE MODE */ if(actual_menu_content != MENU_SURFACE) { @@ -133,7 +135,7 @@ "\017" ,TXT_ScrubTime ,TXT_Maximum - ,settingsGetPointer()->scrubTimerMax + ,pSettings->scrubTimerMax ,TXT_Minutes ); } @@ -144,14 +146,14 @@ textPointer += snprintf(&text[textPointer], 60,\ "%c\002%03u\016\016 %c\017" ,TXT_ScrubTimeReset - ,settingsGetPointer()->scrubTimerCur + ,pSettings->scrubTimerCur ,TXT_Minutes); } strcpy(&text[textPointer],"\n\r"); textPointer += 2; if((line == 0) || (line == 3)) { - switch(settingsGetPointer()->scrubTimerMode) + switch(pSettings->scrubTimerMode) { case SCRUB_TIMER_OFF: default: textPointer += snprintf(&text[textPointer], 60,"%c\002%c%c",TXT_ScrubTimeMode, TXT_2BYTE, TXT2BYTE_MoCtrlNone ); @@ -165,6 +167,35 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; +#ifdef ENABLE_PSCR_MODE + if(pSettings->dive_mode == DIVEMODE_PSCR) + { + if((line == 0) || (line == 4)) + { + textPointer += snprintf(&text[textPointer], 60,\ + "%c\002%02u\016\016%%\017" + ,TXT_PSCRO2Drop + ,pSettings->pscr_o2_drop); + } + strcpy(&text[textPointer],"\n\r"); + textPointer += 2; + if((line == 0) || (line == 5)) + { + textPointer += snprintf(&text[textPointer], 60,\ + "%c\002 1/%02u" + ,TXT_PSCRLungRatio + ,pSettings->pscr_lung_ratio); + } + strcpy(&text[textPointer],"\n\r"); + textPointer += 2; + } +#endif +#ifdef ENABLE_CO2_SUPPORT + if((line == 0) || (line == 6)) + { + textPointer += snprintf(&text[textPointer], 60, "%c", TXT_CO2Sensor); + } +#endif } return StMXTRA; } diff -r 87bee7cc77b3 -r 1b995079c045 Discovery/Src/text_multilanguage.c --- a/Discovery/Src/text_multilanguage.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Discovery/Src/text_multilanguage.c Tue Dec 14 15:36:10 2021 +0100 @@ -453,6 +453,12 @@ static uint8_t text_IT_ClosedCircuit[] = "Ciurcuito chiuso"; static uint8_t text_ES_ClosedCircuit[] = "Circuito cerrado"; +static uint8_t text_EN_PSClosedCircuit[] = "PSC circuit"; +static uint8_t text_DE_PSClosedCircuit[] = "PSC Kreislauf"; +static uint8_t text_FR_PSClosedCircuit[] = "PSC circuit"; +static uint8_t text_IT_PSClosedCircuit[] = "PSC circuit"; +static uint8_t text_ES_PSClosedCircuit[] = "PSC circuit"; + static uint8_t text_EN_Time[] = "Time"; static uint8_t text_DE_Time[] = "Uhrzeit"; static uint8_t text_FR_Time[] = "Heure"; @@ -632,6 +638,13 @@ static uint8_t text_ES_SetFactoryDefaults[] = "Restablecer ajustes de fábrica"; // Menu SYS2 sub +static uint8_t text_EN_ResetBluetooth[] = "Reset bluetooth interface"; +static uint8_t text_DE_ResetBluetooth[] = "Bluetooth interface zurüchsetzen"; +static uint8_t text_FR_ResetBluetooth[] = ""; +static uint8_t text_IT_ResetBluetooth[] = ""; +static uint8_t text_ES_ResetBluetooth[] = ""; + +// Menu SYS2 sub static uint8_t text_EN_SetSampleIndex[] = "Analyse log memory"; static uint8_t text_DE_SetSampleIndex[] = "Prüfe Logbuchspeicher"; static uint8_t text_FR_SetSampleIndex[] = "Maintain log memory"; @@ -1704,6 +1717,37 @@ static uint8_t text_IT_Percent[] = "Percent"; static uint8_t text_ES_Percent[] = "Percent"; +static uint8_t text_EN_PSCRO2Drop[] = "PSCR O2 drop"; +static uint8_t text_DE_PSCRO2Drop[] = "PSCR O2 Abfall"; +static uint8_t text_FR_PSCRO2Drop[] = "PSCR O2 drop"; +static uint8_t text_IT_PSCRO2Drop[] = "PSCR O2 drop"; +static uint8_t text_ES_PSCRO2Drop[] = "PSCR O2 drop"; + +static uint8_t text_EN_LungRatio[] = "PSCR lung ratio"; +static uint8_t text_DE_LungRatio[] = "PSCR Lungen Faktor"; +static uint8_t text_FR_LungRatio[] = "PSCR lung ratio"; +static uint8_t text_IT_LungRatio[] = "PSCR lung ratio"; +static uint8_t text_ES_LungRatio[] = "PSCR lung ratio"; + +static uint8_t text_EN_CheckSettings[] = "Check settings"; +static uint8_t text_DE_CheckSettings[] = "Prüfe Optionen"; +static uint8_t text_FR_CheckSettings[] = "Check settings"; +static uint8_t text_IT_CheckSettings[] = "Check settings"; +static uint8_t text_ES_CheckSettings[] = "Check settings"; + +static uint8_t text_EN_SimPpo2[] = "Sim ppO2"; +static uint8_t text_DE_SimPpo2[] = "Sim ppO2"; +static uint8_t text_FR_SimPpo2[] = "Sim ppO2"; +static uint8_t text_IT_SimPpo2[] = "Sim ppO2"; +static uint8_t text_ES_SimPpo2[] = "Sim ppO2"; + +static uint8_t text_EN_CO2Sensor[] = "CO2 Sensor"; +static uint8_t text_DE_CO2Sensor[] = "CO2 Sensor"; +static uint8_t text_FR_CO2Sensor[] = "CO2 Sensor"; +static uint8_t text_IT_CO2Sensor[] = "CO2 Sensor"; +static uint8_t text_ES_CO2Sensor[] = "CO2 Sensor"; + + /* Lookup Table -------------------------------------------------------------*/ const tText text_array[] = @@ -1770,7 +1814,8 @@ {(uint8_t)TXT_ClosedCircuit, {text_EN_ClosedCircuit, text_DE_ClosedCircuit, text_FR_ClosedCircuit, text_IT_ClosedCircuit, text_ES_ClosedCircuit}}, {(uint8_t)TXT_Apnoe, {text_EN_Apnoe, text_DE_Apnoe, text_FR_Apnoe, text_IT_Apnoe, text_ES_Apnoe}}, {(uint8_t)TXT_Gauge, {text_EN_Gauge, text_DE_Gauge, text_FR_Gauge, text_IT_Gauge, text_ES_Gauge}}, - {(uint8_t)TXT_Sensor, {text_EN_Sensor, text_DE_Sensor, text_FR_Sensor, text_IT_Sensor, text_ES_Sensor}}, + {(uint8_t)TXT_PSClosedCircuit, {text_EN_PSClosedCircuit, text_DE_PSClosedCircuit, text_FR_PSClosedCircuit, text_IT_PSClosedCircuit, text_ES_PSClosedCircuit}}, + {(uint8_t)TXT_Sensor, {text_EN_Sensor, text_DE_Sensor, text_FR_Sensor, text_IT_Sensor, text_ES_Sensor}}, {(uint8_t)TXT_FixedSP, {text_EN_FixedSP, text_DE_FixedSP, text_FR_FixedSP, text_IT_FixedSP, text_ES_FixedSP}}, {(uint8_t)TXT_Decoparameters, {text_EN_Decoparameters, text_DE_Decoparameters, text_FR_Decoparameters, text_IT_Decoparameters, text_ES_Decoparameters}}, {(uint8_t)TXT_LastDecostop, {text_EN_LastDecostop, text_DE_LastDecostop, text_FR_LastDecostop, text_IT_LastDecostop, text_ES_LastDecostop}}, @@ -1787,7 +1832,10 @@ {(uint8_t)TXT_ScrubTimeReset, {text_EN_ScrubTimeReset, text_DE_ScrubTimeReset, text_FR_ScrubTimeReset, text_IT_ScrubTimeReset, text_ES_ScrubTimeReset}}, {(uint8_t)TXT_ScrubTimeMode, {text_EN_ScrubTimeMode, text_DE_ScrubTimeMode, text_FR_ScrubTimeMode, text_IT_ScrubTimeMode, text_ES_ScrubTimeMode}}, {(uint8_t)TXT_Percent, {text_EN_Percent, text_DE_Percent, text_FR_Percent, text_IT_Percent, text_ES_Percent}}, - + {(uint8_t)TXT_PSCRO2Drop, {text_EN_PSCRO2Drop, text_DE_PSCRO2Drop, text_FR_PSCRO2Drop, text_IT_PSCRO2Drop, text_ES_PSCRO2Drop}}, + {(uint8_t)TXT_PSCRLungRatio, {text_EN_LungRatio, text_DE_LungRatio, text_FR_LungRatio, text_IT_LungRatio, text_ES_LungRatio}}, + {(uint8_t)TXT_SimPpo2, {text_EN_SimPpo2, text_DE_SimPpo2, text_FR_SimPpo2, text_IT_SimPpo2, text_ES_SimPpo2}}, + {(uint8_t)TXT_CO2Sensor, {text_EN_CO2Sensor, text_DE_CO2Sensor, text_FR_CO2Sensor, text_IT_CO2Sensor, text_ES_CO2Sensor}}, }; const tText text_array2[] = @@ -1928,6 +1976,7 @@ {(uint8_t)TXT2BYTE_Maintenance, {text_EN_Maintenance, text_DE_Maintenance, text_FR_Maintenance, text_IT_Maintenance, text_ES_Maintenance}}, {(uint8_t)TXT2BYTE_SetBatteryCharge,{text_EN_SetBatteryCharge, text_DE_SetBatteryCharge, text_FR_SetBatteryCharge, text_IT_SetBatteryCharge, text_ES_SetBatteryCharge}}, {(uint8_t)TXT2BYTE_SetFactoryDefaults,{text_EN_SetFactoryDefaults, text_DE_SetFactoryDefaults, text_FR_SetFactoryDefaults, text_IT_SetFactoryDefaults, text_ES_SetFactoryDefaults}}, + {(uint8_t)TXT2BYTE_ResetBluetooth, {text_EN_ResetBluetooth, text_DE_ResetBluetooth, text_FR_ResetBluetooth, text_IT_ResetBluetooth, text_ES_ResetBluetooth}}, {(uint8_t)TXT2BYTE_SetSampleIndex, {text_EN_SetSampleIndex, text_DE_SetSampleIndex, text_FR_SetSampleIndex, text_IT_SetSampleIndex, text_ES_SetSampleIndex}}, {(uint8_t)TXT2BYTE_Reboot, {text_EN_Reboot, text_DE_Reboot, text_FR_Reboot, text_IT_Reboot, text_ES_Reboot}}, @@ -1955,4 +2004,8 @@ {(uint8_t)TXT2BYTE_Minimum, {text_EN_Minimum, text_DE_Minimum, text_FR_Minimum, text_IT_Minimum, text_ES_Minimum}}, {(uint8_t)TXT2BYTE_Normal, {text_EN_Normal, text_DE_Normal, text_FR_Normal, text_IT_Normal, text_ES_Normal}}, {(uint8_t)TXT2BYTE_Maximum, {text_EN_Maximum, text_DE_Maximum, text_FR_Maximum, text_IT_Maximum, text_ES_Maximum}}, + + {(uint8_t)TXT2BYTE_CheckSettings, {text_EN_CheckSettings, text_DE_CheckSettings, text_FR_CheckSettings, text_IT_CheckSettings, text_ES_CheckSettings}}, + + }; diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Inc/batteryCharger.h --- a/Small_CPU/Inc/batteryCharger.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Inc/batteryCharger.h Tue Dec 14 15:36:10 2021 +0100 @@ -31,9 +31,30 @@ /* Includes ------------------------------------------------------------------*/ #include -uint8_t get_charge_status(void); +#define CHARGE_IN_PIN GPIO_PIN_2 +#define CHARGE_IN_GPIO_PORT GPIOC +#define CHARGE_IN_GPIO_ENABLE() __GPIOC_CLK_ENABLE() + +#define CHARGE_OUT_PIN GPIO_PIN_1 +#define CHARGE_OUT_GPIO_PORT GPIOC +#define CHARGE_OUT_GPIO_ENABLE() __GPIOC_CLK_ENABLE() + typedef enum + { + Charger_NotConnected = 0, /* This is identified reading CHARGE_IN_PIN == HIGH */ + Charger_WarmUp, /* Charging started but counter did not yet reach a certain limit (used to debounce connect / disconnect events to avoid multiple increases of statistic charging cycle counter) */ + Charger_Active, /* Charging identified by CHARGE_IN_PIN == LOW for a certain time */ + Charger_Finished, + Charger_LostConnection, /* Intermediate state to debounce disconnecting events (including charging error state like over temperature) */ + Charger_ColdStart, /* Cold start condition => check if an loaded battery has been inserted */ + Charger_END + } chargerState_t; + + +uint8_t get_charge_status(void); void init_battery_charger_status(void); +void set_charge_state(chargerState_t newState); +uint8_t get_charge_state(void); void ReInit_battery_charger_status_pins(void); void DeInit_battery_charger_status_pins(void); void battery_charger_get_status_and_contral_battery_gas_gauge(uint8_t cycleTimeBase); diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Inc/batteryGasGauge.h --- a/Small_CPU/Inc/batteryGasGauge.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Inc/batteryGasGauge.h Tue Dec 14 15:36:10 2021 +0100 @@ -31,6 +31,10 @@ #include +#define BATTERY_DEFAULT_VOLTAGE (6.0f) +#define BATTERY_ENDOF_CHARGE_VOLTAGE (4.05f) +#define BATTERY_CHARGER_CONNECTED_VOLTAGE (4.2f) + void init_battery_gas_gauge(void); float get_voltage(void); diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Inc/externalInterface.h --- a/Small_CPU/Inc/externalInterface.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Inc/externalInterface.h Tue Dec 14 15:36:10 2021 +0100 @@ -32,10 +32,24 @@ #define MAX_ADC_CHANNEL (3u) /* number of channels to be read */ #define EXTERNAL_ADC_NO_DATA 0xFF +#define EXT33V_CONTROL_PIN GPIO_PIN_7 /* PortC */ + void externalInterface_Init(void); +void externalInterface_InitPower33(void); uint8_t externalInterface_StartConversion(uint8_t channel); uint8_t externalInterface_ReadAndSwitch(); float externalInterface_CalculateADCValue(uint8_t channel); float getExternalInterfaceChannel(uint8_t channel); +void externalInterface_SwitchPower33(uint8_t state); +uint8_t externalInterface_isEnabledPower33(); + +void externalInterface_SetCO2Value(uint16_t CO2_ppm); +void externalInterface_SetCO2SignalStrength(uint16_t LED_qa); +uint16_t externalInterface_GetCO2Value(void); +uint16_t externalInterface_GetCO2SignalStrength(void); +void externalInterface_SetCO2State(uint16_t state); +uint16_t externalInterface_GetCO2State(void); + +void externalInterface_ExecuteCmd(uint16_t Cmd); #endif /* EXTERNAL_INTERFACE_H */ diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Inc/uart.h --- a/Small_CPU/Inc/uart.h Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Inc/uart.h Tue Dec 14 15:36:10 2021 +0100 @@ -24,10 +24,24 @@ #include "stm32f4xx_hal.h" -void MX_USART2_UART_Init(void); -void MX_USART2_UART_DeInit(void); + + typedef enum + { + RX_Ready= 0, /* Initial state */ + RX_Data0, /* Process incoming data */ + RX_Data1, + RX_Data2, + RX_Data3, + RX_Data4, + RX_DataComplete + } receiveState_t; + + +void MX_USART1_UART_Init(void); +void MX_USART1_UART_DeInit(void); +void MX_USART1_DMA_Init(void); uint8_t UART_ButtonAdjust(uint8_t *array); - +void HandleUARTData(void); #ifdef __cplusplus } diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/baseCPU2.c --- a/Small_CPU/Src/baseCPU2.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/baseCPU2.c Tue Dec 14 15:36:10 2021 +0100 @@ -142,6 +142,7 @@ #include "scheduler.h" #include "tm_stm32f4_otp.h" #include "externalInterface.h" +#include "uart.h" // From Common/Inc: #include "calc_crush.h" @@ -173,8 +174,8 @@ .signature = "mh", .release_year = 21, - .release_month = 4, - .release_day = 26, + .release_month = 3, + .release_day = 30, .release_sub = 0, /* max 48 with trailing 0 */ @@ -230,6 +231,10 @@ #define WIRELSS_POWER_GPIO_PORT GPIOB #define WIRELSS_POWER_HAL_RCC_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() + +#define LED_CONTROL_PIN GPIO_PIN_3 /* PortC */ +#define MAINCPU_CONTROL_PIN GPIO_PIN_0 /* PortC */ + /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ @@ -353,12 +358,18 @@ HAL_Delay(10); battery_gas_gauge_get_data(); + global.lifeData.battery_voltage = get_voltage(); + global.lifeData.battery_charge = get_charge(); + copyBatteryData(); + MX_SPI3_Init(); if(coldstart != 0xA5) /* Not reading a 0xA5 means the memory cells has not been initialized before => cold start */ { coldstart = 0xA5; - battery_gas_gauge_set(0); + + set_charge_state(Charger_ColdStart); + global.dataSendToMaster.power_on_reset = 1; global.deviceDataSendToMaster.power_on_reset = 1; @@ -373,13 +384,16 @@ } } } - - global.lifeData.battery_voltage = get_voltage(); - global.lifeData.battery_charge = get_charge(); - copyBatteryData(); + else + { + set_charge_state(Charger_NotConnected); + } ADCx_Init(); GPIO_Power_MainCPU_Init(); + + externalInterface_InitPower33(); + global.mode = MODE_POWERUP; #else init_pressure(); @@ -408,6 +422,7 @@ SPI_synchronize_with_Master(); MX_DMA_Init(); MX_SPI1_Init(); + MX_USART1_UART_Init(); SPI_Start_single_TxRx_with_Master(); /* be prepared for the first data exchange */ Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD); EXTI_Test_Button_Init(); @@ -478,7 +493,9 @@ EXTI_Wakeup_Button_Init(); NOT_USED_AT_THE_MOMENT_scheduleSleepMode(); */ + EXTI_Test_Button_DeInit(); + externalInterface_SwitchPower33(false); if (hasExternalClock()) SystemClock_Config_HSI(); sleep_prepare(); @@ -500,6 +517,11 @@ MX_SPI1_Init(); SPI_Start_single_TxRx_with_Master(); + if(externalInterface_isEnabledPower33()) + { + externalInterface_SwitchPower33(true); + } + // EXTILine0_Button_DeInit(); not now, later after testing break; } @@ -793,7 +815,7 @@ GPIO_InitTypeDef GPIO_InitStructure; __GPIOC_CLK_ENABLE(); - GPIO_InitStructure.Pin = GPIO_PIN_3; + GPIO_InitStructure.Pin = LED_CONTROL_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; @@ -805,7 +827,7 @@ GPIO_InitTypeDef GPIO_InitStructure; __GPIOC_CLK_ENABLE(); - GPIO_InitStructure.Pin = GPIO_PIN_3; + GPIO_InitStructure.Pin = LED_CONTROL_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; @@ -815,33 +837,33 @@ void GPIO_new_DEBUG_LOW(void) { #ifdef DEBUG_PIN_ACTIVE - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOC,LED_CONTROL_PIN,GPIO_PIN_RESET); #endif } void GPIO_new_DEBUG_HIGH(void) { #ifdef DEBUG_PIN_ACTIVE - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_SET); + HAL_GPIO_WritePin(GPIOC,LED_CONTROL_PIN,GPIO_PIN_SET); #endif } static void GPIO_Power_MainCPU_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; __GPIOC_CLK_ENABLE(); - GPIO_InitStructure.Pin = GPIO_PIN_0; + GPIO_InitStructure.Pin = MAINCPU_CONTROL_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init( GPIOC, &GPIO_InitStructure); - HAL_GPIO_WritePin( GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); + HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_RESET); } static void GPIO_Power_MainCPU_ON(void) { - HAL_GPIO_WritePin( GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); + HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_RESET); } static void GPIO_Power_MainCPU_OFF(void) { - HAL_GPIO_WritePin( GPIOC, GPIO_PIN_0, GPIO_PIN_SET); + HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_SET); } /** @@ -938,11 +960,7 @@ void sleep_prepare(void) { EXTI_Wakeup_Button_Init(); - /* - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Pin = GPIO_PIN_0; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - */ + compass_sleep(); HAL_Delay(100); accelerator_sleep(); @@ -972,8 +990,8 @@ GPIO_InitStruct.Pin = GPIO_PIN_All - ^ ( GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_14 - | GPIO_PIN_15); /* power off & charger in & charge out & OSC32*/ + ^ ( MAINCPU_CONTROL_PIN | CHARGE_OUT_PIN | CHARGE_IN_PIN | EXT33V_CONTROL_PIN | LED_CONTROL_PIN); /* power off & charger in & charge out & OSC32 & ext33Volt */ + HAL_GPIO_Init( GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0); diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/batteryCharger.c --- a/Small_CPU/Src/batteryCharger.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/batteryCharger.c Tue Dec 14 15:36:10 2021 +0100 @@ -37,29 +37,12 @@ /* Use This compile switch to select the new charger status control implementation */ #define ENABLE_CHARGER_STATUS_V2 -#define CHARGE_IN_PIN GPIO_PIN_2 -#define CHARGE_IN_GPIO_PORT GPIOC -#define CHARGE_IN_GPIO_ENABLE() __GPIOC_CLK_ENABLE() - -#define CHARGE_OUT_PIN GPIO_PIN_1 -#define CHARGE_OUT_GPIO_PORT GPIOC -#define CHARGE_OUT_GPIO_ENABLE() __GPIOC_CLK_ENABLE() - -#define CHARGER_DEBOUNCE_SECONDS (5u) /* 5 seconds used to avoid problems with charger interrupts / disconnections */ +#define CHARGER_DEBOUNCE_SECONDS (6u) /* 6 seconds used to avoid problems with charger interrupts / disconnections */ uint8_t battery_i_charge_status = 0; uint16_t battery_charger_counter = 0; #ifdef ENABLE_CHARGER_STATUS_V2 -typedef enum -{ - Charger_NotConnected = 0, /* This is identified reading CHARGE_IN_PIN == HIGH */ - Charger_WarmUp, /* Charging started but counter did not yet reach a certain limit (used to debounce connect / disconnect events to avoid multiple increases of statistic charging cycle counter) */ - Charger_Active, /* Charging identified by CHARGE_IN_PIN == LOW for a certain time */ - Charger_Finished, - Charger_LostConnection /* Intermediate state to debounce disconnecting events (including charging error state like over temperature) */ -} chargerState_t; - static chargerState_t batteryChargerState = Charger_NotConnected; #endif @@ -73,6 +56,21 @@ return battery_i_charge_status; } +void set_charge_state(uint8_t newState) +{ +#ifdef ENABLE_CHARGER_STATUS_V2 + if(newState < Charger_END) + { + batteryChargerState = newState; + } +#endif +} + +uint8_t get_charge_state(void) +{ + return batteryChargerState; +} + void init_battery_charger_status(void) { #ifdef OSTC_ON_DISCOVERY_HARDWARE @@ -143,6 +141,7 @@ { #ifdef ENABLE_CHARGER_STATUS_V2 static uint8_t notifyChargeComplete = 0; + static float chargeValueAtStart = 0; #endif #ifdef OSTC_ON_DISCOVERY_HARDWARE @@ -150,115 +149,144 @@ #endif #ifdef ENABLE_CHARGER_STATUS_V2 - /* on disconnection or while disconnected */ - if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) + + if(batteryChargerState == Charger_ColdStart) /* wait for the first valid voltage meassurement */ { - switch(batteryChargerState) + if(global.lifeData.battery_voltage != BATTERY_DEFAULT_VOLTAGE) { - case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; - global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; - batteryChargerState = Charger_LostConnection; - battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; - - if(get_voltage() >= 4.1f) /* the charger stops charging when charge current is 1/10. */ - { /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ - batteryChargerState = Charger_Finished; - global.dataSendToMaster.chargeStatus = CHARGER_complete; - global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; - battery_charger_counter = 15; - notifyChargeComplete = 1; - } - break; - case Charger_WarmUp: - case Charger_Finished: - case Charger_LostConnection: if(battery_charger_counter >= cycleTimeBase) - { - battery_charger_counter -= cycleTimeBase; - global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; - global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; - batteryChargerState = Charger_LostConnection; - } - else - { - battery_charger_counter = 0; - battery_i_charge_status = 0; - global.dataSendToMaster.chargeStatus = CHARGER_off; - global.deviceDataSendToMaster.chargeStatus = CHARGER_off; - - if(notifyChargeComplete) - { - battery_gas_gauge_set_charge_full(); - scheduleUpdateDeviceDataChargerFull(); - notifyChargeComplete = 0; - } - batteryChargerState = Charger_NotConnected; - } - break; - default: break; + if(global.lifeData.battery_voltage > BATTERY_ENDOF_CHARGE_VOLTAGE) /* Voltage close to full state => maybe new battery inserted */ + { + battery_gas_gauge_set_charge_full(); + } + else /* unknown state => reset to 0% */ + { + battery_gas_gauge_set(0); + } + batteryChargerState = Charger_NotConnected; } } else - { - /* connected */ - /* wait for disconnection to write and reset */ - switch(batteryChargerState) + { /* on disconnection or while disconnected */ + if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) { - case Charger_NotConnected: battery_i_charge_status = 1; - battery_charger_counter = 0; - batteryChargerState = Charger_WarmUp; - break; - case Charger_LostConnection: batteryChargerState = Charger_Active; - break; - case Charger_WarmUp: battery_charger_counter += cycleTimeBase; - if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) - { - battery_i_charge_status = 2; - scheduleUpdateDeviceDataChargerCharging(); - batteryChargerState = Charger_Active; - } - /* no break */ - case Charger_Finished: - case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; - global.deviceDataSendToMaster.chargeStatus = CHARGER_running; + switch(batteryChargerState) + { + case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; + global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; + batteryChargerState = Charger_LostConnection; + battery_charger_counter = CHARGER_DEBOUNCE_SECONDS; + break; + case Charger_LostConnection: if(get_voltage() >= BATTERY_ENDOF_CHARGE_VOLTAGE) /* the charger stops charging when charge current is 1/10 */ + /* Basically it is OK to rate a charging as complete if a defined voltage is reached */ + { + batteryChargerState = Charger_Finished; + global.dataSendToMaster.chargeStatus = CHARGER_complete; + global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; + notifyChargeComplete = 1; + } + /* no break */ + case Charger_WarmUp: + case Charger_Finished: if(battery_charger_counter >= cycleTimeBase) + { + battery_charger_counter -= cycleTimeBase; + global.dataSendToMaster.chargeStatus = CHARGER_lostConnection; + global.deviceDataSendToMaster.chargeStatus = CHARGER_lostConnection; + batteryChargerState = Charger_LostConnection; + } + else + { + battery_charger_counter = 0; + battery_i_charge_status = 0; + global.dataSendToMaster.chargeStatus = CHARGER_off; + global.deviceDataSendToMaster.chargeStatus = CHARGER_off; - /* drive the output pin high to determine the state of the charger */ - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = CHARGE_OUT_PIN; - GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Speed = GPIO_SPEED_LOW; - HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); - HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); - HAL_Delay(1); + if(notifyChargeComplete) + { + battery_gas_gauge_set_charge_full(); + scheduleUpdateDeviceDataChargerFull(); + notifyChargeComplete = 0; + if(cycleTimeBase > 2) + { + HAL_Delay(50); /* I2C operations are pending in the background. Wait to avoid data loose in caused to potential change to sleep state */ + } + } + else + { + if(chargeValueAtStart < 1.0) /* charging started with unknown value => reset charge state reported by charger */ + { + battery_gas_gauge_set(0); + } + } + batteryChargerState = Charger_NotConnected; + } + break; + default: break; + } + } + else + { + /* connected */ + /* wait for disconnection to write and reset */ + switch(batteryChargerState) + { + case Charger_NotConnected: battery_i_charge_status = 1; + battery_charger_counter = 0; + batteryChargerState = Charger_WarmUp; + chargeValueAtStart = global.lifeData.battery_charge; + break; + case Charger_LostConnection: batteryChargerState = Charger_Active; + break; + case Charger_WarmUp: battery_charger_counter += cycleTimeBase; + if(battery_charger_counter >= CHARGER_DEBOUNCE_SECONDS ) + { + battery_i_charge_status = 2; + scheduleUpdateDeviceDataChargerCharging(); + batteryChargerState = Charger_Active; + } + /* no break */ + case Charger_Finished: + case Charger_Active: global.dataSendToMaster.chargeStatus = CHARGER_running; + global.deviceDataSendToMaster.chargeStatus = CHARGER_running; - if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ - { - batteryChargerState = Charger_Finished; - global.dataSendToMaster.chargeStatus = CHARGER_complete; - global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; - battery_charger_counter = 30; - notifyChargeComplete = 1; - } - else - { - if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ + /* drive the output pin high to determine the state of the charger */ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Pin = CHARGE_OUT_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); + HAL_GPIO_WritePin(CHARGE_OUT_GPIO_PORT, CHARGE_OUT_PIN,GPIO_PIN_SET); + HAL_Delay(1); + + if(HAL_GPIO_ReadPin(CHARGE_IN_GPIO_PORT,CHARGE_IN_PIN)) /* high => charger stopped charging */ + { + batteryChargerState = Charger_Finished; + global.dataSendToMaster.chargeStatus = CHARGER_complete; + global.deviceDataSendToMaster.chargeStatus = CHARGER_complete; + battery_charger_counter = 30; + notifyChargeComplete = 1; + } + else { - batteryChargerState = Charger_Active; - notifyChargeComplete = 0; + if(batteryChargerState == Charger_Finished) /* voltage dropped below the hysteresis again => charging restarted */ + { + batteryChargerState = Charger_Active; + notifyChargeComplete = 0; + } } - } - /* restore high impedance to be able to detect disconnection */ - GPIO_InitStructure.Pin = CHARGE_OUT_PIN; - GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Speed = GPIO_SPEED_LOW; - HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); - HAL_Delay(1); - break; + /* restore high impedance to be able to detect disconnection */ + GPIO_InitStructure.Pin = CHARGE_OUT_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(CHARGE_OUT_GPIO_PORT, &GPIO_InitStructure); + HAL_Delay(1); + break; - default: /* wait for disconnection */ - break; + default: /* wait for disconnection */ + break; + } } } #else diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/batteryGasGauge.c --- a/Small_CPU/Src/batteryGasGauge.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/batteryGasGauge.c Tue Dec 14 15:36:10 2021 +0100 @@ -28,7 +28,7 @@ #include "stm32f4xx_hal.h" #include "i2c.h" -static float battery_f_voltage = 6.0; /* max assumed voltage */ +static float battery_f_voltage = BATTERY_DEFAULT_VOLTAGE; /* max assumed voltage */ static float battery_f_charge_percent = 0; #define BGG_BATTERY_OFFSET (26123) //; 65536-(3,35Ah/0,085mAh) diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/dma.c --- a/Small_CPU/Src/dma.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/dma.c Tue Dec 14 15:36:10 2021 +0100 @@ -34,6 +34,7 @@ */ /* Includes ------------------------------------------------------------------*/ #include "dma.h" +#include "uart.h" /* USER CODE BEGIN 0 */ @@ -55,6 +56,7 @@ /* DMA controller clock enable */ __DMA2_CLK_ENABLE(); + MX_USART1_DMA_Init(); /* DMA interrupt init */ } diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/externalInterface.c --- a/Small_CPU/Src/externalInterface.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/externalInterface.c Tue Dec 14 15:36:10 2021 +0100 @@ -27,8 +27,11 @@ #include "i2c.h" #include "externalInterface.h" #include "scheduler.h" +#include "uart.h" +#include "data_exchange.h" extern SGlobal global; +extern UART_HandleTypeDef huart1; #define ADC_ANSWER_LENGTH (5u) /* 3424 will provide addr + 4 data bytes */ #define ADC_TIMEOUT (10u) /* conversion stuck for unknown reason => restart */ @@ -52,6 +55,10 @@ static uint8_t externalInterfacePresent = 0; float externalChannel_mV[MAX_ADC_CHANNEL]; +static uint8_t externalV33_On = 0; +static uint16_t externalCO2Value; +static uint16_t externalCO2SignalStrength; +static uint16_t externalCO2Status = 0; void externalInterface_Init(void) @@ -65,6 +72,12 @@ global.deviceDataSendToMaster.hw_Info.extADC = 1; } global.deviceDataSendToMaster.hw_Info.checkADC = 1; + +/* init data values */ + externalV33_On = 0; + externalCO2Value = 0; + externalCO2SignalStrength = 0; + externalCO2Status = 0; } @@ -168,3 +181,92 @@ } return retval; } + +void externalInterface_InitPower33(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.Pin = GPIO_PIN_7; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET); +} + + +uint8_t externalInterface_isEnabledPower33() +{ + return externalV33_On; +} +void externalInterface_SwitchPower33(uint8_t state) +{ + if(state != externalV33_On) + { + if(state) + { + HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_RESET); + externalV33_On = 1; + MX_USART1_UART_Init(); + } + else + { + HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET); + externalV33_On = 0; + externalInterface_SetCO2Value(0); + externalInterface_SetCO2SignalStrength(0); + MX_USART1_UART_DeInit(); + } + } +} + +void externalInterface_SetCO2Value(uint16_t CO2_ppm) +{ + externalCO2Value = CO2_ppm; +} + +void externalInterface_SetCO2SignalStrength(uint16_t LED_qa) +{ + externalCO2SignalStrength = LED_qa; +} + +uint16_t externalInterface_GetCO2Value(void) +{ + return externalCO2Value; +} + +uint16_t externalInterface_GetCO2SignalStrength(void) +{ + return externalCO2SignalStrength; +} + + +void externalInterface_SetCO2State(uint16_t state) +{ + externalCO2Status = state; +} + +uint16_t externalInterface_GetCO2State(void) +{ + return externalCO2Status; +} + +void externalInterface_ExecuteCmd(uint16_t Cmd) +{ + char cmdString[10]; + uint8_t cmdLength = 0; + + switch(Cmd & 0x00FF) /* lower byte is reserved for commands */ + { + case EXT_INTERFACE_CO2_CALIB: cmdLength = snprintf(cmdString, 10, "G\r\n"); + break; + default: + break; + } + if(cmdLength != 0) + { + HAL_UART_Transmit(&huart1,(uint8_t*)cmdString,cmdLength,10); + } + return; +} + diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/scheduler.c --- a/Small_CPU/Src/scheduler.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/scheduler.c Tue Dec 14 15:36:10 2021 +0100 @@ -42,6 +42,7 @@ #include "decom.h" #include "tm_stm32f4_otp.h" #include "externalInterface.h" +#include "uart.h" /* uncomment to enable restoting of last known date in case of a power loss (RTC looses timing data) */ /* #define RESTORE_LAST_KNOWN_DATE */ @@ -90,6 +91,7 @@ void copyDeviceData(void); void copyPICdata(void); void copyExtADCdata(); +void copyExtCO2data(); static void schedule_update_timer_helper(int8_t thisSeconds); uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow); @@ -301,6 +303,20 @@ memcpy(&DeviceDataFlash, &global.dataSendToSlave.data.DeviceData, sizeof(SDevice)); deviceDataFlashValid = 1; + + /* handle external interface requests */ + + if((global.dataSendToSlave.data.externalInterface_Cmd && EXT_INTERFACE_33V_ON) != externalInterface_isEnabledPower33()) + { + externalInterface_SwitchPower33(global.dataSendToSlave.data.externalInterface_Cmd && EXT_INTERFACE_33V_ON); + } + + if(global.dataSendToSlave.data.externalInterface_Cmd > EXT_INTERFACE_33V_ON) + { + externalInterface_ExecuteCmd(global.dataSendToSlave.data.externalInterface_Cmd); + } + + #if 0 //TODO: Temporary placed here. Duration ~210 ms. if (global.I2C_SystemStatus != HAL_OK) { @@ -501,6 +517,7 @@ externalInterface_CalculateADCValue(extAdcChannel); copyExtADCdata(); } + copyExtCO2data(); } //Evaluate pressure at 20 ms, 120 ms, 220 ms,.... @@ -761,10 +778,11 @@ void scheduleSurfaceMode(void) { - uint32_t ticksdiff = 0; uint32_t lasttick = 0; uint8_t extAdcChannel = 0; + uint8_t batteryToggle = 0; /* ADC is operating in automatic 2 second cycles => consider for battery charge function call */ + Scheduler.tickstart = HAL_GetTick(); Scheduler.counterSPIdata100msec = 0; Scheduler.counterCompass100msec = 0; @@ -787,6 +805,8 @@ setButtonsNow = 0; } + HandleUARTData(); + /* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */ if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) { @@ -801,6 +821,7 @@ externalInterface_CalculateADCValue(extAdcChannel); copyExtADCdata(); } + copyExtCO2data(); } /* Evaluate pressure at 20 ms, 120 ms, 220 ms,... duration ~22ms] */ @@ -886,8 +907,17 @@ { global.lifeData.desaturation_time_minutes = 0; } - battery_gas_gauge_get_data(); - battery_charger_get_status_and_contral_battery_gas_gauge(1); + + if(!batteryToggle) + { + battery_gas_gauge_get_data(); + battery_charger_get_status_and_contral_battery_gas_gauge(2); + batteryToggle = 1; + } + else + { + batteryToggle = 0; + } copyCnsAndOtuData(); copyTimeData(); @@ -1056,6 +1086,7 @@ if(global.mode == MODE_SLEEP) secondsCount += 2; + externalInterface_InitPower33(); MX_I2C1_Init(); pressure_sensor_get_pressure_raw(); @@ -1069,7 +1100,6 @@ MX_I2C1_Init(); HAL_Delay(100); - if((global.I2C_SystemStatus == HAL_OK) && (!is_init_pressure_done())) { init_pressure(); @@ -1080,7 +1110,7 @@ { pressure_sensor_get_temperature_raw(); battery_gas_gauge_get_data(); -// ReInit_battery_charger_status_pins(); + ReInit_battery_charger_status_pins(); battery_charger_get_status_and_contral_battery_gas_gauge(30); // DeInit_battery_charger_status_pins(); secondsCount = 0; @@ -1363,7 +1393,7 @@ } break; - case MODE_SLEEP: + case MODE_SLEEP: case MODE_SHUTDOWN: break; } @@ -1636,6 +1666,26 @@ } } +void copyExtCO2data() +{ + uint16_t value; + + if(externalInterface_GetCO2State()) + { + value = externalInterface_GetCO2Value(); + global.dataSendToMaster.data[0].CO2_ppm = value; + value = externalInterface_GetCO2SignalStrength(); + global.dataSendToMaster.data[0].CO2_signalStrength = value; + global.dataSendToMaster.data[0].externalInterface_CmdAnswer = externalInterface_GetCO2State(); + externalInterface_SetCO2State(EXT_INTERFACE_33V_ON); /* clear command responses */ + } + else + { + global.dataSendToMaster.data[0].CO2_ppm = 0; + global.dataSendToMaster.data[0].CO2_signalStrength = 0; + global.dataSendToMaster.data[0].externalInterface_CmdAnswer = 0; + } +} typedef enum { diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/spi.c --- a/Small_CPU/Src/spi.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/spi.c Tue Dec 14 15:36:10 2021 +0100 @@ -350,7 +350,6 @@ /* stop data exchange? */ if (global.mode == MODE_SHUTDOWN) { - global.mode = MODE_SLEEP; global.dataSendToSlavePending = 0; global.dataSendToSlaveIsValid = 1; global.dataSendToSlaveIsNotValidCount = 0; diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/stm32f4xx_hal_msp_v3.c --- a/Small_CPU/Src/stm32f4xx_hal_msp_v3.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/stm32f4xx_hal_msp_v3.c Tue Dec 14 15:36:10 2021 +0100 @@ -229,14 +229,18 @@ { GPIO_InitTypeDef GPIO_InitStruct; - if(huart->Instance==USART2) + if(huart->Instance==USART1) { - __USART2_CLK_ENABLE(); - GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; + __GPIOA_CLK_ENABLE(); + __USART1_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_LOW; - GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + GPIO_InitStruct.Speed = GPIO_SPEED_FAST; //GPIO_SPEED_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_10; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } @@ -244,10 +248,11 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) { - if(huart->Instance==USART2) + if(huart->Instance==USART1) { - __USART2_CLK_DISABLE(); - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); + HAL_NVIC_DisableIRQ(USART1_IRQn); + __USART1_CLK_DISABLE(); + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); } } diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/stm32f4xx_it_v3.c --- a/Small_CPU/Src/stm32f4xx_it_v3.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/stm32f4xx_it_v3.c Tue Dec 14 15:36:10 2021 +0100 @@ -58,6 +58,9 @@ extern RTC_HandleTypeDef RTCHandle; extern ADC_HandleTypeDef AdcHandle; +extern UART_HandleTypeDef huart1; +extern DMA_HandleTypeDef hdma_usart1_rx; + /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ @@ -233,6 +236,11 @@ * @retval None */ +void DMA2_Stream5_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_usart1_rx); +} + /******************************************************************************/ /* STM32F4xx Peripherals Interrupt Handlers */ @@ -295,6 +303,12 @@ HAL_ADC_IRQHandler(&AdcHandle); } + +void USART1_IRQHandler(void) +{ + HAL_UART_IRQHandler(&huart1); +} + /** * @brief This function handles PPP interrupt request. * @param None diff -r 87bee7cc77b3 -r 1b995079c045 Small_CPU/Src/uart.c --- a/Small_CPU/Src/uart.c Mon Nov 01 12:39:34 2021 +0100 +++ b/Small_CPU/Src/uart.c Tue Dec 14 15:36:10 2021 +0100 @@ -20,57 +20,193 @@ */ /* Includes ------------------------------------------------------------------*/ #include "uart.h" +#include "externalInterface.h" +#include "data_exchange.h" /* Private variables ---------------------------------------------------------*/ -UART_HandleTypeDef huart2; +#define CHUNK_SIZE (20u) /* the DMA will handle chunk size transfers */ +#define CHUNKS_PER_BUFFER (3u) +UART_HandleTypeDef huart1; + +DMA_HandleTypeDef hdma_usart1_rx; +uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow fariations in buffer read time */ +static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ +static uint8_t rxReadIndex; /* Index at which new data is stared */ +static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ +static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */ +float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ +float LED_ZeroOffset = 0.0; +float pCO2 = 0.0; /* Exported functions --------------------------------------------------------*/ -void MX_USART2_UART_Init(void) +void MX_USART1_UART_Init(void) { -/* pullup special */ - GPIO_InitTypeDef GPIO_InitStructure; - __GPIOA_CLK_ENABLE(); - GPIO_InitStructure.Pin = GPIO_PIN_2; - GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStructure.Pull = GPIO_PULLUP; - GPIO_InitStructure.Speed = GPIO_SPEED_FAST; - HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); +/* regular init */ + + huart1.Instance = USART1; + huart1.Init.BaudRate = 9600; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + + HAL_UART_Init(&huart1); + + rxReadIndex = 0; + lastCmdIndex = 0; + rxWriteIndex = 0; + dmaActive = 0; +} -/* regular init */ - huart2.Instance = USART2; - huart2.Init.BaudRate = 1200; - huart2.Init.WordLength = UART_WORDLENGTH_8B; - huart2.Init.StopBits = UART_STOPBITS_1; - huart2.Init.Parity = UART_PARITY_NONE; - huart2.Init.Mode = UART_MODE_TX_RX; - huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart2.Init.OverSampling = UART_OVERSAMPLING_16; - HAL_UART_Init(&huart2); +void MX_USART1_UART_DeInit(void) +{ + HAL_DMA_DeInit(&hdma_usart1_rx); + HAL_UART_DeInit(&huart1); +} + +void MX_USART1_DMA_Init() +{ + /* DMA controller clock enable */ + __DMA2_CLK_ENABLE(); + + /* Peripheral DMA init*/ + hdma_usart1_rx.Instance = DMA2_Stream5; + hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4; + hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; //DMA_MEMORY_TO_PERIPH; + hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart1_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart1_rx.Init.Mode = DMA_NORMAL; + hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_usart1_rx); + + __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx); + + /* DMA interrupt init */ + HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); } -uint8_t UART_ButtonAdjust(uint8_t *array) +uint32_t dataValue = 0; + +void HandleUARTData(void) { - uint8_t answer[4]; - - HAL_UART_Transmit(&huart2,array,4,1000); - HAL_UART_Receive(&huart2,answer,4,2000); - if( (answer[0] == array[0]) - &&(answer[1] == array[1]) - &&(answer[2] == array[2]) - &&(answer[3] == array[3])) - return 1; - else - return 0; + uint8_t localRX = rxReadIndex; + uint8_t dataType = 0; + static receiveState_t rxState = RX_Ready; + static uint32_t lastReceiveTick = 0; + + while(localRX != rxWriteIndex) + { + lastReceiveTick = HAL_GetTick(); + if(rxState == RX_Ready) /* identify data content */ + { + switch(rxBuffer[localRX]) + { + case 'l': + case 'D': + case 'Z': + dataType = rxBuffer[localRX]; + rxState = RX_Data0; + dataValue = 0; + break; + + default: /* unknown or corrupted => ignore */ + break; + } + } + else if((rxState >= RX_Data0) && (rxState <= RX_Data4)) + { + if((rxBuffer[localRX] >= '0') && (rxBuffer[localRX] <= '9')) + { + dataValue = dataValue * 10 + (rxBuffer[localRX] - '0'); + rxState++; + } + } + if((rxBuffer[localRX] == ' ') || (rxBuffer[localRX] == '\n')) /* Abort data detection */ + { + if(rxState == RX_DataComplete) + { + if(externalInterface_GetCO2State() == 0) + { + externalInterface_SetCO2State(EXT_INTERFACE_33V_ON); + } + switch(dataType) + { + case 'D': externalInterface_SetCO2SignalStrength(dataValue); + break; + case 'l': LED_ZeroOffset = dataValue; + break; + case 'Z': externalInterface_SetCO2Value(dataValue); + break; + default: break; + } + } + if(rxState != RX_Data0) /* reset state machine because message in wrong format */ + { + rxState = RX_Ready; + } + } + + localRX++; + rxReadIndex++; + if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + localRX = 0; + rxReadIndex = 0; + } + } + + if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000) /* check for communication timeout */ + { + externalInterface_SetCO2State(0); + } + + if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ + { + if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) + { + dmaActive = 1; + } + } } -void MX_USART2_UART_DeInit(void) +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - HAL_UART_DeInit(&huart2); + if(huart == &huart1) + { + dmaActive = 0; + rxWriteIndex+=CHUNK_SIZE; + if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + rxWriteIndex = 0; + } + if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */ + { + if(externalInterface_isEnabledPower33()) + { + if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) + { + dmaActive = 1; + } + } + } + } } + + + + + + /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/