Mercurial > public > ostc4
diff Discovery/Src/data_exchange_main.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children | 8f8ea3a32e82 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/data_exchange_main.c Sat Apr 28 11:52:34 2018 +0200 @@ -0,0 +1,1379 @@ +/** + ****************************************************************************** + * @file data_exchange_main.c + * @author heinrichs weikamp gmbh + * @date 13-Oct-2014 + * @version V0.0.3 + * @since 17-Feb-2016 + + * @brief Communication with the second CPU == RTE system + * + @verbatim + ============================================================================== + ##### Version Changes ##### + ============================================================================== + 160217 V0.0.3 pStateUsed->decolistXXXXX.tickstamp = HAL_GetTick(); added + 150627 V0.0.2 + + ============================================================================== + ##### How to use ##### + ============================================================================== + + ============================================================================== + ##### Button, Set Time, Clear Deco etc Request ##### + ============================================================================== + was updated (151207) for buttons and clear deco at the moment only + using requestNecessary and checking in DataEX_copy_to_LifeData() + Hence if there is no confirm from the smallCPU on the data after the request + the request will be send again. + + ============================================================================== + ##### Device Data ##### + ============================================================================== + + main CPU always sends the device data info that it has at the moment + + on start it is INT32_MIN, INT32_MAX and 0 + as initialized in data_central.c variable declaration + + second small CPU gets request to send its device data + + on receiption the data is merged with the data in externLogbookFlash, + stored on the externLogbookFlash and from now on send to small CPU + + ============================================================================== + ##### Magnet Reset ##### + ============================================================================== + + @endverbatim + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2> + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> // for memcopy +#include "stm32f4xx_hal.h" +#include "stdio.h" +#include "ostc.h" +#include "settings.h" +#include "data_central.h" +#include "data_exchange_main.h" +#include "base.h" +#include "decom.h" +#include "calc_crush.h" /* for vpm_init */ +#include "simulation.h" +#include "tCCR.h" +#include "timer.h" +#include "buehlmann.h" +#include "externLogbookFlash.h" +#include "bonex_mini.h" // for voltage to battery percentage + + +/* Expoted variables --------------------------------------------------------*/ +uint8_t wasPowerOn = 0; +confirmbit8_Type requestNecessary = { .uw = 0 }; +uint8_t wasUpdateNotPowerOn = 0; +uint8_t scooterFoundThisPowerOnCylce = 0; + +/* Private variables with external access ------------------------------------*/ + + +/* Private variables ---------------------------------------------------------*/ +uint8_t told_reset_logik_alles_ok = 0; + +SDataReceiveFromMaster dataOut; +SDataExchangeSlaveToMaster dataIn; + +uint32_t systick_last; +uint8_t data_old__lost_connection_to_slave_counter_temp = 0; +uint8_t data_old__lost_connection_to_slave_counter_retry = 0; +uint32_t data_old__lost_connection_to_slave_counter_total = 0; + +/* Private types -------------------------------------------------------------*/ + +typedef enum +{ + CPU2_TRANSFER_STOP = 0x00, /*!< */ + CPU2_TRANSFER_TEST_REQUEST = 0x01, /*!< */ + CPU2_TRANSFER_TEST_RECEIVE = 0x02, /*!< */ + CPU2_TRANSFER_SEND_OK = 0x03, /*!< */ + CPU2_TRANSFER_SEND_FALSE = 0x04, /*!< */ + CPU2_TRANSFER_DATA = 0x05, /*!< */ +}CPU2_TRANSFER_StatusTypeDef; + +const uint8_t header_test_request[4] = {0xBB, 0x00, 0x00, 0xBB}; +const uint8_t header_test_receive[4] = {0xBB, 0x01, 0x01, 0xBB}; +const uint8_t header_false[4] = {0xBB, 0xFF, 0xFF, 0xBB}; +const uint8_t header_correct[4] = {0xBB, 0xCC, 0xCC, 0xBB}; +const uint8_t header_data[4] = {0xAA, 0x01, 0x01, 0xAA}; + +/* Private function prototypes -----------------------------------------------*/ +uint8_t DataEX_check_header_and_footer_ok(void); +uint8_t DataEX_check_header_and_footer_devicedata(void); +void DataEX_check_DeviceData(void); + +/* Exported functions --------------------------------------------------------*/ +void DataEX_set_update_RTE_not_power_on(void) +{ + wasUpdateNotPowerOn = 1; +} + + +uint8_t DataEX_was_power_on(void) +{ + return wasPowerOn; +} + +uint8_t count_DataEX_Error_Handler = 0; +uint8_t last_error_DataEX_Error_Handler = 0; + +void DataEX_Error_Handler(uint8_t answer) +{ + count_DataEX_Error_Handler++; + last_error_DataEX_Error_Handler = answer; + return; +} + + +uint32_t DataEX_lost_connection_count(void) +{ + return data_old__lost_connection_to_slave_counter_total; +} + + +uint32_t DataEX_time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow) +{ + + if(ticksstart <= ticksnow) + { + return ticksnow - ticksstart; + } + else + { + return 0xFFFFFFFF - ticksstart + ticksnow; + } + +} + +SDataReceiveFromMaster * dataOutGetPointer(void) +{ + return &dataOut; +} + +void DataEX_init(void) +{ + SDiveState * pStateReal = stateRealGetPointerWrite(); + pStateReal->data_old__lost_connection_to_slave = 1; + data_old__lost_connection_to_slave_counter_temp = 0; + data_old__lost_connection_to_slave_counter_total = 0; + + memset((void *)&dataOut, 0, sizeof(SDataReceiveFromMaster)); + // old 160307: for(int i=0;i<EXCHANGE_BUFFERSIZE;i++) +// *(uint8_t *)(((uint32_t)&dataOut) + i) = 0; + + dataOut.header.checkCode[0] = 0xBB; + dataOut.header.checkCode[1] = 0x01; + dataOut.header.checkCode[2] = 0x01; + dataOut.header.checkCode[3] = 0xBB; + + dataOut.footer.checkCode[0] = 0xF4; + dataOut.footer.checkCode[1] = 0xF3; + dataOut.footer.checkCode[2] = 0xF2; + dataOut.footer.checkCode[3] = 0xF1; + + + pStateReal->lifeData.scooterType = 0xFF; + pStateReal->lifeData.scooterWattstunden = 0; + pStateReal->lifeData.scooterRestkapazitaet = 0; + pStateReal->lifeData.scooterDrehzahl = 0; + pStateReal->lifeData.scooterSpannung = 0; + pStateReal->lifeData.scooterTemperature = 0; + pStateReal->lifeData.scooterAmpere = 0; + pStateReal->lifeData.scooterRestkapazitaetWhBased = 0; + pStateReal->lifeData.scooterRestkapazitaetVoltageBased = 0; + pStateReal->lifeData.scooterAgeInMilliSeconds = 0; + + systick_last = HAL_GetTick() - 100; +} + + +void DataEx_call_helper_requests(void) +{ + static uint8_t setDateWasSend = 0; + static uint8_t setTimeWasSend = 0; + static uint8_t calibrateCompassWasSend = 0; + static uint8_t setButtonSensitivityWasSend = 0; + static uint8_t clearDecoWasSend = 0; + static uint8_t getDeviceDataWasSend = 0; + static uint8_t setAccidentFlagWasSend = 0; + static uint8_t setEndDiveWasSend = 0; + + if(getDeviceDataWasSend) + { + dataOut.getDeviceDataNow = 0; + requestNecessary.ub.devicedata = 1; + } + getDeviceDataWasSend = 0; + if(dataOut.getDeviceDataNow) + { + getDeviceDataWasSend = 1; + } + + if(setEndDiveWasSend) + { + dataOut.setEndDive = 0; + //requestNecessary.ub.XXX = 1; not implemented and no space here + } + setEndDiveWasSend = 0; + if(dataOut.setEndDive) + { + setEndDiveWasSend = 1; + } + + if(setAccidentFlagWasSend) + { + dataOut.setAccidentFlag = 0; + requestNecessary.ub.accident = 1; + } + setAccidentFlagWasSend = 0; + if(dataOut.setAccidentFlag) + { + setAccidentFlagWasSend = 1; + } + + if(setDateWasSend) + { + dataOut.setDateNow = 0; + requestNecessary.ub.date = 1; + } + setDateWasSend = 0; + if(dataOut.setDateNow) + { + setDateWasSend = 1; + } + + if(setTimeWasSend) + { + dataOut.setTimeNow = 0; + requestNecessary.ub.time = 1; + } + setTimeWasSend = 0; + if(dataOut.setTimeNow) + { + setTimeWasSend = 1; + } + + if(calibrateCompassWasSend) + { + dataOut.calibrateCompassNow = 0; + requestNecessary.ub.compass = 1; + } + calibrateCompassWasSend = 0; + if(dataOut.calibrateCompassNow) + { + calibrateCompassWasSend = 1; + } + + if(clearDecoWasSend) + { + dataOut.clearDecoNow = 0; + requestNecessary.ub.clearDeco = 1; + } + if(dataOut.clearDecoNow) + { + clearDecoWasSend = 1; + } + + if(setButtonSensitivityWasSend) + { + dataOut.setButtonSensitivityNow = 0; + requestNecessary.ub.button = 1; + } + setButtonSensitivityWasSend = 0; + if(dataOut.setButtonSensitivityNow) + { + setButtonSensitivityWasSend = 1; + } +} + + +uint8_t DataEX_call(void) +{ + uint8_t SPI_DMA_answer = 0; + + HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_SET); + delayMicros(10); + + /* one cycle with NotChipSelect true to clear slave spi buffer */ + + if(data_old__lost_connection_to_slave_counter_temp >= 3) + { + data_old__lost_connection_to_slave_counter_temp = 0; + data_old__lost_connection_to_slave_counter_retry++; + } + else + { + HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET); + } + + DataEx_call_helper_requests(); + + systick_last = HAL_GetTick(); + +//HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_RESET); /* only for testing with Oscilloscope */ + + SPI_DMA_answer = HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)&dataOut, (uint8_t *)&dataIn, EXCHANGE_BUFFERSIZE+1); + if(SPI_DMA_answer != HAL_OK) + DataEX_Error_Handler(SPI_DMA_answer); +//HAL_Delay(3); +//HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_SET); /* only for testing with Oscilloscope */ + + return 1; +} + +void DateEx_copy_to_dataOut(void) +{ + const SDiveState * pStateReal = stateRealGetPointer(); + SSettings *settings = settingsGetPointer(); + + if(get_globalState() == StStop) + dataOut.mode = MODE_SHUTDOWN; + else + dataOut.mode = 0; + + dataOut.diveModeInfo = pStateReal->diveSettings.diveMode; // hw 170215 + + memcpy(&dataOut.data.DeviceData, stateDeviceGetPointer(), sizeof(SDevice)); + + dataOut.data.VPMconservatism = pStateReal->diveSettings.vpm_conservatism; + dataOut.data.actualGas = pStateReal->lifeData.actualGas; + dataOut.data.ambient_pressure_mbar_ceiling = (pStateReal->decolistBuehlmann.output_ceiling_meter * 100) + (pStateReal->lifeData.pressure_surface_bar * 1000); + dataOut.data.divetimeToCreateLogbook = settings->divetimeToCreateLogbook; + dataOut.data.timeoutDiveReachedZeroDepth = settings->timeoutDiveReachedZeroDepth; + + dataOut.data.offsetPressureSensor_mbar = settings->offsetPressure_mbar; + dataOut.data.offsetTemperatureSensor_centiDegree = settings->offsetTemperature_centigrad; + + if((hardwareDataGetPointer()->primarySerial <= 32) || (((hardwareDataGetPointer()->primarySerial == 72) && (hardwareDataGetPointer()->secondarySerial == 15)))) + { + dataOut.revisionHardware = 0x00; + dataOut.revisionCRCx0x7A = 0x7A; + } + else + if(hardwareDataGetPointer()->primarySerial < 0xFFFF) + { + dataOut.revisionHardware = hardwareDataGetPointer()->revision8bit; + dataOut.revisionCRCx0x7A = hardwareDataGetPointer()->revision8bit ^ 0x7A; + } + else + { + dataOut.revisionHardware = 0xFF; + dataOut.revisionCRCx0x7A = 0xFF; + } + + /* + for(int i = 0; i< 16; i++) + { + dataOut.data.VPM_adjusted_critical_radius_he[i] = pStateReal->vpm.adjusted_critical_radius_he[i]; + dataOut.data.VPM_adjusted_critical_radius_n2[i] = pStateReal->vpm.adjusted_critical_radius_n2[i]; + dataOut.data.VPM_adjusted_crushing_pressure_he[i] = pStateReal->vpm.adjusted_crushing_pressure_he[i]; + dataOut.data.VPM_adjusted_crushing_pressure_n2[i] = pStateReal->vpm.adjusted_crushing_pressure_n2[i]; + dataOut.data.VPM_initial_allowable_gradient_he[i] = pStateReal->vpm.initial_allowable_gradient_he[i]; + dataOut.data.VPM_initial_allowable_gradient_n2[i] = pStateReal->vpm.initial_allowable_gradient_n2[i]; + dataOut.data.VPM_max_actual_gradient[i] = pStateReal->vpm.max_actual_gradient[i]; + } +*/ + + if(DataEX_check_header_and_footer_ok() && !told_reset_logik_alles_ok) + { + MX_tell_reset_logik_alles_ok(); + told_reset_logik_alles_ok = 1; + } + + if(DataEX_check_header_and_footer_ok() && (dataIn.power_on_reset == 1)) + { + if(!wasUpdateNotPowerOn) + wasPowerOn = 1; + + RTC_DateTypeDef Sdate; + RTC_TimeTypeDef Stime; + + translateDate(settings->backup_localtime_rtc_dr, &Sdate); + translateTime(settings->backup_localtime_rtc_tr, &Stime); + + dataOut.data.newTime = Stime; + dataOut.setTimeNow = 1; + dataOut.data.newDate = Sdate; + dataOut.setDateNow = 1; + + settingsHelperButtonSens_keepPercentageValues(settingsGetPointerStandard()->ButtonResponsiveness[3], settings->ButtonResponsiveness); + setButtonResponsiveness(settings->ButtonResponsiveness); + + // hw 160720 new lastKnownBatteryPercentage + if(!wasUpdateNotPowerOn) + { +// dataOut.data.newBatteryGaugePercentageFloat = settingsGetPointer()->lastKnownBatteryPercentage; + dataOut.data.newBatteryGaugePercentageFloat = 0; + dataOut.setBatteryGaugeNow = 1; + } + } +} + + +void DataEX_copy_to_deco(void) +{ + SDiveState * pStateUsed; + if(decoLock == DECO_CALC_running) + return; + if(stateUsed == stateRealGetPointer()) + pStateUsed = stateRealGetPointerWrite(); + else + pStateUsed = stateSimGetPointerWrite(); + + + if(decoLock == DECO_CALC_init_as_is_start_of_dive) + { + vpm_init(&pStateUsed->vpm, pStateUsed->diveSettings.vpm_conservatism, 0, 0); + buehlmann_init(); + timer_init(); + resetEvents(); + pStateUsed->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; + /* + * ToDo by Peter + * copy VPM stuff etc. pp. + * was void initDiveState(SDiveSettings * pDiveSettings, SVpm * pVpm); + */ + } + + + + if(decoLock == DECO_CALC_FINSHED_Buehlmann) + { + + } + switch(decoLock) + { + + //Deco_calculation finished + case DECO_CALC_FINSHED_vpm: + memcpy(&pStateUsed->decolistVPM,&stateDeco.decolistVPM,sizeof(SDecoinfo)); + pStateUsed->decolistVPM.tickstamp = HAL_GetTick(); + pStateUsed->vpm.deco_zone_reached = stateDeco.vpm.deco_zone_reached; + for(int i = 0; i< 16; i++) + { + pStateUsed->vpm.adjusted_critical_radius_he[i] = stateDeco.vpm.adjusted_critical_radius_he[i]; + pStateUsed->vpm.adjusted_critical_radius_n2[i] = stateDeco.vpm.adjusted_critical_radius_n2[i]; + pStateUsed->vpm.adjusted_crushing_pressure_he[i] = stateDeco.vpm.adjusted_crushing_pressure_he[i]; + pStateUsed->vpm.adjusted_crushing_pressure_n2[i] = stateDeco.vpm.adjusted_crushing_pressure_n2[i]; + pStateUsed->vpm.initial_allowable_gradient_he[i] = stateDeco.vpm.initial_allowable_gradient_he[i]; + pStateUsed->vpm.initial_allowable_gradient_n2[i] = stateDeco.vpm.initial_allowable_gradient_n2[i]; + pStateUsed->vpm.max_actual_gradient[i] = stateDeco.vpm.max_actual_gradient[i]; + } + break; + case DECO_CALC_FINSHED_Buehlmann: + memcpy(&pStateUsed->decolistBuehlmann,&stateDeco.decolistBuehlmann,sizeof(SDecoinfo)); + pStateUsed->decolistBuehlmann.tickstamp = HAL_GetTick(); + //Copy Data to be stored if regular Buehlmann, not FutureBuehlmann + pStateUsed->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = stateDeco.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero; + break; + case DECO_CALC_FINSHED_FutureBuehlmann: + memcpy(&pStateUsed->decolistFutureBuehlmann,&stateDeco.decolistFutureBuehlmann,sizeof(SDecoinfo)); + pStateUsed->decolistFutureBuehlmann.tickstamp = HAL_GetTick(); + break; + case DECO_CALC_FINSHED_Futurevpm: + memcpy(&pStateUsed->decolistFutureVPM,&stateDeco.decolistFutureVPM,sizeof(SDecoinfo)); + pStateUsed->decolistFutureVPM.tickstamp = HAL_GetTick(); + break; + } + + //Copy Inputdata from stateReal to stateDeco + memcpy(&stateDeco.lifeData,&pStateUsed->lifeData,sizeof(SLifeData)); + memcpy(&stateDeco.diveSettings,&pStateUsed->diveSettings,sizeof(SDiveSettings)); + + stateDeco.vpm.deco_zone_reached = pStateUsed->vpm.deco_zone_reached; + // memcpy(&stateDeco.vpm,&pStateUsed->vpm,sizeof(SVpm)); + for(int i = 0; i< 16; i++) + { + stateDeco.vpm.max_crushing_pressure_he[i] = pStateUsed->vpm.max_crushing_pressure_he[i]; + stateDeco.vpm.max_crushing_pressure_n2[i] = pStateUsed->vpm.max_crushing_pressure_n2[i]; + stateDeco.vpm.adjusted_critical_radius_he[i] = pStateUsed->vpm.adjusted_critical_radius_he[i]; + stateDeco.vpm.adjusted_critical_radius_n2[i] = pStateUsed->vpm.adjusted_critical_radius_n2[i]; + } + decoLock = DECO_CALC_ready; +} + + +void DataEX_helper_copy_deviceData(SDeviceLine *lineWrite, const SDeviceLine *lineRead) +{ + lineWrite->date_rtc_dr = lineRead->date_rtc_dr; + lineWrite->time_rtc_tr = lineRead->time_rtc_tr; + lineWrite->value_int32 = lineRead->value_int32; +} + + + +void DataEX_helper_SetTime(RTC_TimeTypeDef inStimestructure, uint32_t *outTimetmpreg) +{ + inStimestructure.TimeFormat = RTC_HOURFORMAT_24; + + *outTimetmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(inStimestructure.Hours) << 16U) | \ + ((uint32_t)RTC_ByteToBcd2(inStimestructure.Minutes) << 8U) | \ + ((uint32_t)RTC_ByteToBcd2(inStimestructure.Seconds)) | \ + (((uint32_t)inStimestructure.TimeFormat) << 16U)); +} + + +void DataEX_helper_SetDate(RTC_DateTypeDef inSdatestructure, uint32_t *outDatetmpreg) +{ + *outDatetmpreg = (((uint32_t)RTC_ByteToBcd2(inSdatestructure.Year) << 16U) | \ + ((uint32_t)RTC_ByteToBcd2(inSdatestructure.Month) << 8U) | \ + ((uint32_t)RTC_ByteToBcd2(inSdatestructure.Date)) | \ + ((uint32_t)inSdatestructure.WeekDay << 13U)); +} + + + +void DataEX_helper_set_Unknown_Date_deviceData(SDeviceLine *lineWrite) +{ + RTC_DateTypeDef sdatestructure; + RTC_TimeTypeDef stimestructure; + + stimestructure.Hours = 1; + stimestructure.Minutes = 0; + stimestructure.Seconds = 0; + + sdatestructure.Date = 1; + sdatestructure.Month = 1; + sdatestructure.Year = 16; + setWeekday(&sdatestructure); + + DataEX_helper_SetTime(stimestructure, &lineWrite->time_rtc_tr); + DataEX_helper_SetDate(sdatestructure, &lineWrite->date_rtc_dr); +} + + +uint8_t DataEX_helper_Check_And_Correct_Date_deviceData(SDeviceLine *lineWrite) +{ + RTC_DateTypeDef sdatestructure; + RTC_TimeTypeDef stimestructure; + + // from lineWrite to structure + translateDate(lineWrite->date_rtc_dr, &sdatestructure); + translateTime(lineWrite->time_rtc_tr, &stimestructure); + + if( (sdatestructure.Year >= 15) + && (sdatestructure.Year <= 30) + && (sdatestructure.Month <= 12)) + return 0; + + + DataEX_helper_set_Unknown_Date_deviceData(lineWrite); + return 1; +} + + +uint8_t DataEX_helper_Check_And_Correct_Value_deviceData(SDeviceLine *lineWrite, int32_t from, int32_t to) +{ + if(lineWrite->value_int32 >= from && lineWrite->value_int32 <= to) + return 0; + + if(lineWrite->value_int32 < from) + lineWrite->value_int32 = from; + else + lineWrite->value_int32 = to; + + DataEX_helper_set_Unknown_Date_deviceData(lineWrite); + return 0; +} + + +void DataEX_check_DeviceData(void) +{ + SDevice *DeviceData = stateDeviceGetPointerWrite(); + + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->batteryChargeCompleteCycles); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->batteryChargeCycles); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->depthMaximum); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->diveCycles); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->hoursOfOperation); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->temperatureMaximum); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->temperatureMinimum); + DataEX_helper_Check_And_Correct_Date_deviceData(&DeviceData->voltageMinimum); + + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->batteryChargeCompleteCycles, 0, 10000); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->batteryChargeCycles, 0, 20000); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->depthMaximum, 0, (500*100)+1000); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->diveCycles, 0, 20000); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->hoursOfOperation, 0, 1000000); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->temperatureMaximum, -30*100, 150*100); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->temperatureMinimum, -30*100, 150*100); + DataEX_helper_Check_And_Correct_Value_deviceData(&DeviceData->voltageMinimum, -1*1000, 6*1000); +} + + +void DataEX_merge_DeviceData_and_store(void) +{ + uint16_t dataLengthRead; + SDevice DeviceDataFlash; + SDevice *DeviceData = stateDeviceGetPointerWrite(); + + dataLengthRead = ext_flash_read_devicedata((uint8_t *)&DeviceDataFlash,sizeof(SDevice)); + + if(dataLengthRead == 0) + { + ext_flash_write_devicedata(); + return; + } + +/* + SDeviceLine batteryChargeCycles; + SDeviceLine batteryChargeCompleteCycles; + SDeviceLine temperatureMinimum; + SDeviceLine temperatureMaximum; + SDeviceLine depthMaximum; + SDeviceLine diveCycles; + SDeviceLine voltageMinimum; +*/ + + /* max values */ + if(DeviceData->batteryChargeCompleteCycles.value_int32 < DeviceDataFlash.batteryChargeCompleteCycles.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->batteryChargeCompleteCycles, &DeviceDataFlash.batteryChargeCompleteCycles); + } + if(DeviceData->batteryChargeCycles.value_int32 < DeviceDataFlash.batteryChargeCycles.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->batteryChargeCycles, &DeviceDataFlash.batteryChargeCycles); + } + if(DeviceData->temperatureMaximum.value_int32 < DeviceDataFlash.temperatureMaximum.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->temperatureMaximum, &DeviceDataFlash.temperatureMaximum); + } + if(DeviceData->depthMaximum.value_int32 < DeviceDataFlash.depthMaximum.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->depthMaximum, &DeviceDataFlash.depthMaximum); + } + if(DeviceData->diveCycles.value_int32 < DeviceDataFlash.diveCycles.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->diveCycles, &DeviceDataFlash.diveCycles); + } + + /* min values */ + if(DeviceData->temperatureMinimum.value_int32 > DeviceDataFlash.temperatureMinimum.value_int32) + { + DataEX_helper_copy_deviceData(&DeviceData->temperatureMinimum, &DeviceDataFlash.temperatureMinimum); + } + // Voltage minimum, keep limit to 2.0 Volt; hw 09.09.2015 + if(DeviceData->voltageMinimum.value_int32 > DeviceDataFlash.voltageMinimum.value_int32) + { + if(DeviceDataFlash.voltageMinimum.value_int32 > 2000) // do not copy back 2000 and below + DataEX_helper_copy_deviceData(&DeviceData->voltageMinimum, &DeviceDataFlash.voltageMinimum); + } + if(DeviceData->voltageMinimum.value_int32 < 2000) + DeviceData->voltageMinimum.value_int32 = 2000; + + DataEX_check_DeviceData (); + ext_flash_write_devicedata(); +} + + +void DataEX_copy_to_DeviceData(void) +{ + SDataExchangeSlaveToMasterDeviceData * dataInDevice = (SDataExchangeSlaveToMasterDeviceData *)&dataIn; + SDevice * pDeviceState = stateDeviceGetPointerWrite(); + + memcpy(pDeviceState, &dataInDevice->DeviceData[dataInDevice->boolDeviceData], sizeof(SDevice)); +} + + +void DataEX_copy_to_VpmRepetitiveData(void) +{ + SDataExchangeSlaveToMasterDeviceData * dataInDevice = (SDataExchangeSlaveToMasterDeviceData *)&dataIn; + SVpmRepetitiveData * pVpmState = stateVpmRepetitiveDataGetPointerWrite(); + + if(dataInDevice->boolVpmRepetitiveDataValid) + { + memcpy(pVpmState, &dataInDevice->VpmRepetitiveData, sizeof(SVpmRepetitiveData)); + pVpmState->is_data_from_RTE_CPU = 1; + } +} + + +void DataEX_control_connection_while_asking_for_sleep(void) +{ + if(!DataEX_check_header_and_footer_ok()) + { + if(DataEX_check_header_and_footer_devicedata()) + { + data_old__lost_connection_to_slave_counter_retry = 0; + data_old__lost_connection_to_slave_counter_temp = 0; + stateRealGetPointerWrite()->data_old__lost_connection_to_slave = 0; + } + else + { + stateRealGetPointerWrite()->data_old__lost_connection_to_slave = 1; + data_old__lost_connection_to_slave_counter_temp += 1; + data_old__lost_connection_to_slave_counter_total += 1; + } + } +} + + +void DataEX_copy_to_LifeData(_Bool *modeChangeFlag) +{ + SDiveState * pStateReal = stateRealGetPointerWrite(); + static uint16_t getDeviceDataAfterStartOfMainCPU = 20; + + /* internal sensor: HUD data + */ + for(int i=0;i<3;i++) + { + pStateReal->lifeData.ppO2Sensor_bar[i] = get_ppO2Sensor_bar(i); + pStateReal->lifeData.sensorVoltage_mV[i] = get_sensorVoltage_mV(i); + } + pStateReal->lifeData.HUD_battery_voltage_V = get_HUD_battery_voltage_V(); + + + // wireless - �ltere daten aufr�umen + for(int i=0;i<=(2*NUM_GASES+1);i++) + { + if(pStateReal->lifeData.bottle_bar[i]) + { + if((pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] == 0) || (pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] > 60000)) + { + pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] = 0; + pStateReal->lifeData.bottle_bar[i] = 0; + } + else + pStateReal->lifeData.bottle_bar_age_MilliSeconds[i] += 100; + } + } + +/* Why? hw 8.6.2015 + if(DataEX_check_header_and_footer_ok() && dataIn.power_on_reset) + { + return; + } +*/ + if(!DataEX_check_header_and_footer_ok()) + { + if(DataEX_check_header_and_footer_devicedata()) + { + DataEX_copy_to_DeviceData(); + DataEX_merge_DeviceData_and_store(); + DataEX_copy_to_VpmRepetitiveData(); + data_old__lost_connection_to_slave_counter_temp = 0; + data_old__lost_connection_to_slave_counter_retry = 0; + pStateReal->data_old__lost_connection_to_slave = 0; + } + else + { + pStateReal->data_old__lost_connection_to_slave = 1; + data_old__lost_connection_to_slave_counter_temp += 1; + data_old__lost_connection_to_slave_counter_total += 1; + } + return; + } + + if(getDeviceDataAfterStartOfMainCPU) + { + getDeviceDataAfterStartOfMainCPU--; + if(getDeviceDataAfterStartOfMainCPU == 0) + { + dataOut.getDeviceDataNow = 1; + getDeviceDataAfterStartOfMainCPU = 10*60*10;// * 100ms + } + } + + /* new 151207 hw */ + if(requestNecessary.uw != 0) + { + if(((dataIn.confirmRequest.uw) & CRBUTTON) != 0) + { + requestNecessary.ub.button = 0; + } + + if(requestNecessary.ub.button == 1) + { + setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness); + } +/* + } + if((dataIn.confirmRequest.ub.clearDeco != 1) && (requestNecessary.ub.clearDeco == 1)) + { + clearDeco(); // is dataOut.clearDecoNow = 1; + } +*/ + } + requestNecessary.uw = 0; // clear all + + float ambient, surface, density, meter; + SSettings *pSettings; + + /* uint8_t IAmStolenPleaseKillMe; + */ + if(settingsGetPointer()->IAmStolenPleaseKillMe > 3) + { + pSettings->salinity = 0; + dataIn.data[dataIn.boolPressureData].surface_mbar = 999; + dataIn.data[dataIn.boolPressureData].pressure_mbar = 98971; + dataIn.mode = MODE_DIVE; + } + + pSettings = settingsGetPointer(); + ambient = dataIn.data[dataIn.boolPressureData].pressure_mbar / 1000.0f; + surface = dataIn.data[dataIn.boolPressureData].surface_mbar / 1000.0f; + + density = ((float)( 100 + pSettings->salinity)) / 100.0f; + meter = (ambient - surface); + meter /= (0.09807f * density); + + + pStateReal->pressure_uTick_old = pStateReal->pressure_uTick_new; + pStateReal->pressure_uTick_new = dataIn.data[dataIn.boolPressureData].pressure_uTick; + pStateReal->pressure_uTick_local_new = HAL_GetTick(); + + if(ambient < (surface + 0.04f)) + + pStateReal->lifeData.dateBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_dr; + pStateReal->lifeData.timeBinaryFormat = dataIn.data[dataIn.boolTimeData].localtime_rtc_tr; + + dataOut.setAccidentFlag = 0; + + //Start of diveMode? + if(pStateReal->mode != MODE_DIVE && dataIn.mode == MODE_DIVE) + { + if(modeChangeFlag) + *modeChangeFlag = 1; + if(stateUsed == stateSimGetPointer()) + { + simulation_exit(); + } + // new 170508 + settingsGetPointer()->bluetoothActive = 0; + MX_Bluetooth_PowerOff(); + //Init dive Mode + decoLock = DECO_CALC_init_as_is_start_of_dive; + pStateReal->lifeData.boolResetAverageDepth = 1; + pStateReal->lifeData.boolResetStopwatch = 1; + } + + //End of diveMode? + if(pStateReal->mode == MODE_DIVE && dataIn.mode != MODE_DIVE) + { + if(modeChangeFlag) + *modeChangeFlag = 1; + createDiveSettings(); + + if(pStateReal->warnings.cnsHigh) + { + if(pStateReal->lifeData.cns >= 130) + dataOut.setAccidentFlag += ACCIDENT_CNSLVL2; + else if(pStateReal->lifeData.cns >= 100) + dataOut.setAccidentFlag += ACCIDENT_CNS; + } + if(pStateReal->warnings.decoMissed) + dataOut.setAccidentFlag += ACCIDENT_DECOSTOP; + } + pStateReal->mode = dataIn.mode; + pStateReal->chargeStatus = dataIn.chargeStatus; + + pStateReal->lifeData.pressure_ambient_bar = ambient; + pStateReal->lifeData.pressure_surface_bar = surface; + if(is_ambient_pressure_close_to_surface(&pStateReal->lifeData)) + { + pStateReal->lifeData.depth_meter = 0; + } + else + { + pStateReal->lifeData.depth_meter = meter; + } + pStateReal->lifeData.temperature_celsius = dataIn.data[dataIn.boolPressureData].temperature; + pStateReal->lifeData.ascent_rate_meter_per_min = dataIn.data[dataIn.boolPressureData].ascent_rate_meter_per_min; + if(pStateReal->mode != MODE_DIVE) + pStateReal->lifeData.max_depth_meter = 0; + else + { + if(meter > pStateReal->lifeData.max_depth_meter) + 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; + + 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; + pStateReal->lifeData.surface_time_seconds = (int32_t)dataIn.data[dataIn.boolTimeData].surfacetime_seconds; + + pStateReal->lifeData.compass_heading = dataIn.data[dataIn.boolCompassData].compass_heading; + pStateReal->lifeData.compass_roll = dataIn.data[dataIn.boolCompassData].compass_roll; + pStateReal->lifeData.compass_pitch = dataIn.data[dataIn.boolCompassData].compass_pitch; + + pStateReal->lifeData.compass_DX_f = dataIn.data[dataIn.boolCompassData].compass_DX_f; + pStateReal->lifeData.compass_DY_f = dataIn.data[dataIn.boolCompassData].compass_DY_f; + pStateReal->lifeData.compass_DZ_f = dataIn.data[dataIn.boolCompassData].compass_DZ_f; + + pStateReal->compass_uTick_old = pStateReal->compass_uTick_new; + pStateReal->compass_uTick_new = dataIn.data[dataIn.boolCompassData].compass_uTick; + pStateReal->compass_uTick_local_new = HAL_GetTick(); + + pStateReal->lifeData.cns = dataIn.data[dataIn.boolToxicData].cns; + pStateReal->lifeData.otu = dataIn.data[dataIn.boolToxicData].otu; + pStateReal->lifeData.no_fly_time_minutes = dataIn.data[dataIn.boolToxicData].no_fly_time_minutes; + pStateReal->lifeData.desaturation_time_minutes = dataIn.data[dataIn.boolToxicData].desaturation_time_minutes; + + memcpy(pStateReal->lifeData.tissue_nitrogen_bar, dataIn.data[dataIn.boolTisssueData].tissue_nitrogen_bar,sizeof(pStateReal->lifeData.tissue_nitrogen_bar)); + memcpy(pStateReal->lifeData.tissue_helium_bar, dataIn.data[dataIn.boolTisssueData].tissue_helium_bar,sizeof(pStateReal->lifeData.tissue_helium_bar)); + + if(pStateReal->mode == MODE_DIVE) + { + for(int i= 0; i <16; i++) + { + pStateReal->vpm.max_crushing_pressure_he[i] = dataIn.data[dataIn.boolCrushingData].max_crushing_pressure_he[i]; + pStateReal->vpm.max_crushing_pressure_n2[i] = dataIn.data[dataIn.boolCrushingData].max_crushing_pressure_n2[i]; + pStateReal->vpm.adjusted_critical_radius_he[i] = dataIn.data[dataIn.boolCrushingData].adjusted_critical_radius_he[i]; + pStateReal->vpm.adjusted_critical_radius_n2[i] = dataIn.data[dataIn.boolCrushingData].adjusted_critical_radius_n2[i]; + } + } + + /* battery and ambient light sensors + */ + pStateReal->lifeData.ambient_light_level = dataIn.data[dataIn.boolAmbientLightData].ambient_light_level; + pStateReal->lifeData.battery_charge = dataIn.data[dataIn.boolBatteryData].battery_charge; + pStateReal->lifeData.battery_voltage = dataIn.data[dataIn.boolBatteryData].battery_voltage; + +/* now in ext_flash_write_settings() // hw 161027 + * if((pStateReal->lifeData.battery_charge > 1) && !DataEX_was_power_on() && ((uint8_t)(pStateReal->lifeData.battery_charge) != 0x10)) // get rid of 16% (0x10) + * pSettings->lastKnownBatteryPercentage = (uint8_t)(pStateReal->lifeData.battery_charge); + */ + + /* OC and CCR but no sensors -> moved to updateSetpointStateUsed(); + float oxygen = 0; + if(pStateReal->diveSettings.diveMode == 0) + { + oxygen = 1.00f; + oxygen -= ((float)pStateReal->lifeData.actualGas.nitrogen_percentage)/100.0f; + oxygen -= ((float)pStateReal->lifeData.actualGas.helium_percentage)/100.0f; + pStateReal->lifeData.ppO2 = pStateReal->lifeData.pressure_ambient_bar * oxygen; + } + else if(pStateReal->diveSettings.diveMode == 1) + { + pStateReal->lifeData.ppO2 = ((float)pStateReal->lifeData.actualGas.setPoint_cbar) /100; + } + */ + + /* apnea specials + */ + if(pStateReal->diveSettings.diveMode == DIVEMODE_Apnea) + { + if(pStateReal->mode != MODE_DIVE) + { + pStateReal->lifeData.apnea_total_max_depth_meter = 0; + pStateReal->lifeData.apnea_last_dive_time_seconds = 0; + pStateReal->lifeData.apnea_last_max_depth_meter = 0; + } + else + { + if(pStateReal->lifeData.max_depth_meter > pStateReal->lifeData.apnea_total_max_depth_meter) + pStateReal->lifeData.apnea_total_max_depth_meter = pStateReal->lifeData.max_depth_meter; + } + + if(pStateReal->lifeData.dive_time_seconds > 15) + { + pStateReal->lifeData.apnea_last_dive_time_seconds = pStateReal->lifeData.dive_time_seconds; + } + + if(pStateReal->lifeData.counterSecondsShallowDepth) + { + if(pStateReal->lifeData.max_depth_meter > 1.5f) + { + pStateReal->lifeData.apnea_last_max_depth_meter = pStateReal->lifeData.max_depth_meter; + } + // eset max_depth_meter, average_depth_meter and internal values + pStateReal->lifeData.max_depth_meter = 0; + pStateReal->lifeData.boolResetAverageDepth = 1; + pStateReal->lifeData.boolResetStopwatch = 1; + } + } + + /* average depth + */ + float *AvgDepthValue = &pStateReal->lifeData.average_depth_meter; + float DepthNow = pStateReal->lifeData.depth_meter; + uint32_t *AvgDepthCount = &pStateReal->lifeData.internal.average_depth_meter_Count; + uint32_t *AvgDepthTimer = &pStateReal->lifeData.internal.average_depth_last_update_dive_time_seconds_without_surface_time; + uint32_t AvgSecondsSinceLast; + uint32_t DiveTime = pStateReal->lifeData.dive_time_seconds_without_surface_time; + + if(pStateReal->lifeData.boolResetAverageDepth) + { + *AvgDepthValue = DepthNow; + *AvgDepthCount = 1; + *AvgDepthTimer = DiveTime; + pStateReal->lifeData.boolResetAverageDepth = 0; + } + else if (DiveTime > *AvgDepthTimer) + { + AvgSecondsSinceLast = DiveTime - *AvgDepthTimer; + for(int i=0;i<AvgSecondsSinceLast;i++) + { + *AvgDepthValue = (*AvgDepthValue * *AvgDepthCount + DepthNow) / (*AvgDepthCount + 1); + *AvgDepthCount += 1; + } + *AvgDepthTimer = DiveTime; + } + if(*AvgDepthCount == 0) + *AvgDepthValue = 0; + + + /* stop watch + */ + if(pStateReal->lifeData.boolResetStopwatch) + { + pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds = pStateReal->lifeData.dive_time_seconds; + pStateReal->lifeData.boolResetStopwatch = 0; + } + pStateReal->lifeData.stopwatch_seconds = pStateReal->lifeData.dive_time_seconds - pStateReal->lifeData.internal.stopwatch_start_at_this_dive_time_seconds; + + /* wireless data + */ + uint16_t wirelessData[4][3]; + for(int i=0;i<4;i++) + { + pStateReal->lifeData.wireless_data[i].ageInMilliSeconds = dataIn.data[dataIn.boolWirelessData].wireless_data[i].ageInMilliSeconds; + pStateReal->lifeData.wireless_data[i].status = dataIn.data[dataIn.boolWirelessData].wireless_data[i].status; + pStateReal->lifeData.wireless_data[i].numberOfBytes = dataIn.data[dataIn.boolWirelessData].wireless_data[i].numberOfBytes; + for(int j=0;j<12;j++) + pStateReal->lifeData.wireless_data[i].data[j] = dataIn.data[dataIn.boolWirelessData].wireless_data[i].data[j]; + } + + /* old stuff + // crc - is done in RTE 160325 + // size at the moment 4 bytes + one empty + crc -> minimum 5 bytes (+ crc) + // kopieren: Id, Wert, Alter + for(int i=0;i<4;i++) + { + uint8_t numberOfBytes = pStateReal->lifeData.wireless_data[i].numberOfBytes - 1; + + if((numberOfBytes < 5) || (numberOfBytes > 7)) + { + wirelessData[i][0] = 0; + wirelessData[i][1] = 0; + wirelessData[i][2] = 0; + } + else + { + if((crc32c_checksum(pStateReal->lifeData.wireless_data[i].data, numberOfBytes, 0, 0) & 0xFF)!= pStateReal->lifeData.wireless_data[i].data[numberOfBytes]) + { +// no crc is send at the moment +wirelessData[i][0] = (pStateReal->lifeData.wireless_data[i].data[0] * 256) + pStateReal->lifeData.wireless_data[i].data[1]; +wirelessData[i][1] = (pStateReal->lifeData.wireless_data[i].data[3] * 256) + pStateReal->lifeData.wireless_data[i].data[4]; +wirelessData[i][2] = pStateReal->lifeData.wireless_data[i].ageInMilliSeconds; + +// wirelessData[i][0] = 0; +// wirelessData[i][1] = 0; +// wirelessData[i][2] = 0; + + } + + else + { + wirelessData[i][0] = (pStateReal->lifeData.wireless_data[i].data[0] * 256) + pStateReal->lifeData.wireless_data[i].data[1]; + wirelessData[i][1] = (pStateReal->lifeData.wireless_data[i].data[3] * 256) + pStateReal->lifeData.wireless_data[i].data[4]; + wirelessData[i][2] = pStateReal->lifeData.wireless_data[i].ageInMilliSeconds; + } + } + } +*/ + // neu 160412 + for(int i=0;i<4;i++) + { + if(pStateReal->lifeData.wireless_data[i].numberOfBytes == 10) + { + wirelessData[i][0] = (pStateReal->lifeData.wireless_data[i].data[0] >> 4) & 0x7F; + wirelessData[i][1] = 0; + wirelessData[i][2] = pStateReal->lifeData.wireless_data[i].ageInMilliSeconds; + } + else + { + wirelessData[i][0] = 0; + wirelessData[i][1] = 0; + wirelessData[i][2] = 0; + } + } + + // aussortieren doppelte ids, j�ngster datensatz ist relevant + for(int i=0;i<3;i++) + { + if(wirelessData[i][0]) + { + for(int j=i+1; j<4; j++) + { + if(wirelessData[i][0] == wirelessData[j][0]) + { + if(wirelessData[i][2] > wirelessData[j][2]) + { + wirelessData[i][0] = wirelessData[j][0]; + wirelessData[i][1] = wirelessData[j][1]; + wirelessData[i][2] = wirelessData[j][2]; + } + wirelessData[j][0] = 0; + wirelessData[j][1] = 0; + wirelessData[j][2] = 0; + } + } + } + } +/* + // neu 160325 + for(int i=0;i<4;i++) + { + if(pStateReal->lifeData.wireless_data[i].numberOfBytes == 10) + { + wirelessData[i][0] = (pStateReal->lifeData.wireless_data[i].data[0] * 256) + pStateReal->lifeData.wireless_data[i].data[1]; + wirelessData[i][1] = (pStateReal->lifeData.wireless_data[i].data[3] * 256) + pStateReal->lifeData.wireless_data[i].data[4]; + wirelessData[i][2] = pStateReal->lifeData.wireless_data[i].ageInMilliSeconds; + } + else + { + wirelessData[i][0] = 0; + wirelessData[i][1] = 0; + wirelessData[i][2] = 0; + } + } + + // aussortieren doppelte ids, j�ngster datensatz ist relevant + for(int i=0;i<3;i++) + { + if(wirelessData[i][0]) + { + for(int j=i+1; j<4; j++) + { + if(wirelessData[i][0] == wirelessData[j][0]) + { + if(wirelessData[i][2] > wirelessData[j][2]) + { + wirelessData[i][0] = wirelessData[j][0]; + wirelessData[i][1] = wirelessData[j][1]; + wirelessData[i][2] = wirelessData[j][2]; + } + wirelessData[j][0] = 0; + wirelessData[j][1] = 0; + wirelessData[j][2] = 0; + } + } + } + } +*/ +/* old + // copy to lifeData + for(int i=0;i<4;i++) + { + if((wirelessData[i][0]) && (wirelessData[i][2]) && (wirelessData[i][2] < 60000)) + { + for(int j=1;j<=(2*NUM_GASES+1);j++) + { + if(pStateReal->diveSettings.gas[j].bottle_wireless_id == wirelessData[i][0]) + { + pStateReal->lifeData.bottle_bar[j] = wirelessData[i][1]; + pStateReal->lifeData.bottle_bar_age_MilliSeconds[j] = wirelessData[i][2]; + break; + } + } + } + } +*/ + // new: Bonex + float scooterSpeedFloat; + int32_t scooterRemainingBattCapacity; + + for(int i=0;i<4;i++) + { + if((wirelessData[i][0]))// && (wirelessData[i][2]) && (wirelessData[i][2] < 60000)) + { + pStateReal->lifeData.scooterType = (pStateReal->lifeData.wireless_data[i].data[0] >> 4) & 0x07; + pStateReal->lifeData.scooterWattstunden = ((uint16_t)((((uint16_t)(pStateReal->lifeData.wireless_data[i].data[0] & 0x0F) << 8) | (pStateReal->lifeData.wireless_data[i].data[1])))); +// pStateReal->lifeData.scooterWattstunden = pStateReal->lifeData.wireless_data[i].data[0] & 0x0F; +// pStateReal->lifeData.scooterWattstunden *= 256; +// pStateReal->lifeData.scooterWattstunden += pStateReal->lifeData.wireless_data[i].data[1]; + pStateReal->lifeData.scooterRestkapazitaet = pStateReal->lifeData.wireless_data[i].data[2]; + pStateReal->lifeData.scooterDrehzahl = ((uint16_t)( (int16_t)((pStateReal->lifeData.wireless_data[i].data[4] << 8) | (pStateReal->lifeData.wireless_data[i].data[3])))); + pStateReal->lifeData.scooterSpannung = ((float)(pStateReal->lifeData.wireless_data[i].data[5])) / 5.0f; + pStateReal->lifeData.scooterTemperature = ((uint16_t)( (int16_t)((pStateReal->lifeData.wireless_data[i].data[7] << 8) | (pStateReal->lifeData.wireless_data[i].data[6])))); + pStateReal->lifeData.scooterAmpere = pStateReal->lifeData.wireless_data[i].data[9] >> 1; + pStateReal->lifeData.scooterAgeInMilliSeconds = pStateReal->lifeData.wireless_data[i].ageInMilliSeconds; + + if(pStateReal->lifeData.scooterWattstunden > 0) + scooterRemainingBattCapacity = settingsGetPointer()->scooterBattSize / pStateReal->lifeData.scooterWattstunden; + else + scooterRemainingBattCapacity = 100; + + + if(scooterRemainingBattCapacity < 0) + scooterRemainingBattCapacity = 0; + if(scooterRemainingBattCapacity > 100) + scooterRemainingBattCapacity = 100; + pStateReal->lifeData.scooterRestkapazitaetWhBased = scooterRemainingBattCapacity; + +// BONEX_calc_new_ResidualCapacity(&pStateReal->lifeData.scooterRestkapazitaetVoltageBased, (uint32_t)(1000 * pStateReal->lifeData.scooterSpannung),1000,1); + pStateReal->lifeData.scooterRestkapazitaetVoltageBased = BONEX_mini_ResidualCapacityVoltageBased(pStateReal->lifeData.scooterSpannung, pStateReal->lifeData.scooterAgeInMilliSeconds); + + scooterSpeedFloat = (float)pStateReal->lifeData.scooterDrehzahl; + scooterSpeedFloat /= (37.0f / 1.1f); // 3700 rpm = 110 m/min + switch(settingsGetPointer()->scooterDrag) + { + case 1: + scooterSpeedFloat *= 0.95f; + break; + case 2: + scooterSpeedFloat *= 0.85f; + break; + case 3: + scooterSpeedFloat *= 0.75f; + break; + default: + break; + } + switch(settingsGetPointer()->scooterLoad) + { + case 1: + scooterSpeedFloat *= 0.90f; + break; + case 2: + scooterSpeedFloat *= 0.80f; + break; + case 3: + scooterSpeedFloat *= 0.70f; + break; + case 4: + scooterSpeedFloat *= 0.60f; + break; + default: + break; + } + if(scooterSpeedFloat < 0) + pStateReal->lifeData.scooterSpeed = 0; + else + if(scooterSpeedFloat > 255) + pStateReal->lifeData.scooterSpeed = 255; + else + pStateReal->lifeData.scooterSpeed = (uint16_t)scooterSpeedFloat; + + if(!scooterFoundThisPowerOnCylce && (pStateReal->lifeData.scooterAgeInMilliSeconds > 0)) + scooterFoundThisPowerOnCylce = 1; + } + } + + /* PIC data + */ + for(int i=0;i<4;i++) + { + pStateReal->lifeData.buttonPICdata[i] = dataIn.data[dataIn.boolPICdata].button_setting[i]; + } + + /* sensorErrors + */ + pStateReal->sensorErrorsRTE = dataIn.sensorErrors; + + /* end + */ + data_old__lost_connection_to_slave_counter_temp = 0; + data_old__lost_connection_to_slave_counter_retry = 0; + pStateReal->data_old__lost_connection_to_slave = 0; +} + + +uint8_t DataEX_check_RTE_version__needs_update(void) +{ + if(data_old__lost_connection_to_slave_counter_retry > 10) + return 1; + else + { + if(stateRealGetPointer()->data_old__lost_connection_to_slave == 0) + { + setActualRTEversion(dataIn.RTE_VERSION_high, dataIn.RTE_VERSION_low); + + if(RTEminimum_required_high() < dataIn.RTE_VERSION_high) + return 0; + else + if((RTEminimum_required_high() == dataIn.RTE_VERSION_high) && (RTEminimum_required_low() <= dataIn.RTE_VERSION_low)) + return 0; + else + return 1; + } + else + return 0; + } +} + + +uint8_t DataEX_scooterDataFound(void) +{ + return scooterFoundThisPowerOnCylce; +} + + +uint8_t DataEX_scooterFoundAndValidLicence(void) +{ + if(getLicence() != LICENCEBONEX) + return 0; + else + return scooterFoundThisPowerOnCylce; +//return 0xFF; +//return LICENCEBONEX; +} + + /* Private functions ---------------------------------------------------------*/ + +uint8_t DataEX_check_header_and_footer_ok(void) +{ + if(dataIn.header.checkCode[0] != 0xA1) + return 0; + if(dataIn.header.checkCode[1] != 0xA2) + return 0; + if(dataIn.header.checkCode[2] != 0xA3) + return 0; + if(dataIn.header.checkCode[3] != 0xA4) + return 0; + if(dataIn.footer.checkCode[0] != 0xE1) + return 0; + if(dataIn.footer.checkCode[1] != 0xE2) + return 0; + if(dataIn.footer.checkCode[2] != 0xE3) + return 0; + if(dataIn.footer.checkCode[3] != 0xE4) + return 0; + + return 1; +} + +uint8_t DataEX_check_header_and_footer_devicedata(void) +{ + if(dataIn.header.checkCode[0] != 0xDF) + return 0; + if(dataIn.header.checkCode[1] != 0xDE) + return 0; + if(dataIn.header.checkCode[2] != 0xDD) + return 0; + if(dataIn.header.checkCode[3] != 0xDC) + return 0; + if(dataIn.footer.checkCode[0] != 0xE1) + return 0; + if(dataIn.footer.checkCode[1] != 0xE2) + return 0; + if(dataIn.footer.checkCode[2] != 0xE3) + return 0; + if(dataIn.footer.checkCode[3] != 0xE4) + return 0; + + return 1; +} + + +