diff Discovery/Src/tCCR.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children 74a8296a2318
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/tCCR.c	Sat Apr 28 11:52:34 2018 +0200
@@ -0,0 +1,366 @@
+///////////////////////////////////////////////////////////////////////////////
+/// -*- coding: UTF-8 -*-
+///
+/// \file   Discovery/Src/tCCR.c
+/// \brief  HUD data via optical port
+/// \author Heinrichs Weikamp gmbh
+/// \date   18-Dec-2014
+///
+/// \details
+///
+/// $Id$
+///////////////////////////////////////////////////////////////////////////////
+/// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh
+///
+///     This program is free software: you can redistribute it and/or modify
+///     it under the terms of the GNU General Public License as published by
+///     the Free Software Foundation, either version 3 of the License, or
+///     (at your option) any later version.
+///
+///     This program is distributed in the hope that it will be useful,
+///     but WITHOUT ANY WARRANTY; without even the implied warranty of
+///     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+///     GNU General Public License for more details.
+///
+///     You should have received a copy of the GNU General Public License
+///     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//////////////////////////////////////////////////////////////////////////////
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "tCCR.h"
+#include "ostc.h"
+#include "data_central.h"
+#include "data_exchange.h"
+#include "check_warning.h"
+
+/* Private types -------------------------------------------------------------*/
+typedef struct
+{
+    uint8_t hud_firmwareVersion;
+    bit8_Type status_byte;
+    uint16_t sensor_voltage_100uV[3];
+    uint8_t sensor_ppo2_cbar[3];
+    uint8_t temp1;
+    uint16_t battery_voltage_mV;
+    uint16_t checksum;
+} 	SIrLink;
+
+/* Private variables ---------------------------------------------------------*/
+SIrLink receiveHUD[2];
+uint8_t boolHUDdata = 0;
+uint8_t data_old__lost_connection_to_HUD = 1;
+
+uint8_t receiveHUDraw[16];
+
+uint8_t StartListeningToUART_HUD = 0;
+uint16_t count = 0;
+
+/* Private variables with external access via get_xxx() function -------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+void tCCR_fallbackToFixedSetpoint(void);
+
+#ifndef USART_IR_HUD
+
+void tCCR_init(void)
+{
+}
+void tCCR_control(void)
+{
+}
+void tCCR_test(void)
+{
+}
+void tCCR_restart(void)
+{
+}
+float get_ppO2Sensor_bar(uint8_t sensor_id)
+{
+}
+float get_sensorVoltage_mV(uint8_t sensor_id)
+{
+}
+float get_HUD_battery_voltage_V(void)
+{
+}
+void tCCR_tick(void)
+{
+}
+
+#else
+/* Exported functions --------------------------------------------------------*/
+
+float get_ppO2Sensor_bar(uint8_t sensor_id)
+{
+    if((sensor_id > 2) || data_old__lost_connection_to_HUD)
+        return 0;
+
+    return (float)(receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id]) / 100.0f;
+}
+
+float get_sensorVoltage_mV(uint8_t sensor_id)
+{
+    if((sensor_id > 2) || data_old__lost_connection_to_HUD)
+        return 0;
+
+    return (float)(receiveHUD[boolHUDdata].sensor_voltage_100uV[sensor_id]) / 10.0f;
+}
+
+float get_HUD_battery_voltage_V(void)
+{
+    if(data_old__lost_connection_to_HUD)
+        return 0;
+
+    return (float)(receiveHUD[boolHUDdata].battery_voltage_mV) / 1000.0f;
+}
+
+
+void test_HUD_sensor_values_outOfBounds(int8_t * outOfBouds1, int8_t * outOfBouds2, int8_t * outOfBouds3)
+{
+    uint8_t sensorNotActiveBinary;
+    uint8_t sensorActive[3];
+
+    // test1: user deactivation
+    sensorNotActiveBinary = stateUsed->diveSettings.ppo2sensors_deactivated;
+
+    for(int i=0;i<3;i++)
+        sensorActive[i] = 1;
+
+    if(sensorNotActiveBinary)
+    {
+        if(sensorNotActiveBinary & 1)
+            sensorActive[0] = 0;
+
+        if(sensorNotActiveBinary & 2)
+            sensorActive[1] = 0;
+
+        if(sensorNotActiveBinary & 4)
+            sensorActive[2] = 0;
+    }
+
+    // test2: mV of remaining sensors
+    for(int i=0;i<3;i++)
+    {
+        if(sensorActive[i])
+        {
+            if(	(receiveHUD[boolHUDdata].sensor_voltage_100uV[i] < 80) ||
+                    (receiveHUD[boolHUDdata].sensor_voltage_100uV[i] > 2500))
+            {
+                sensorActive[i] = 0;
+                switch(i)
+                {
+                    case 0:
+                        sensorNotActiveBinary |= 1;
+                    break;
+                    case 1:
+                        sensorNotActiveBinary |= 2;
+                    break;
+                    case 2:
+                        sensorNotActiveBinary |= 4;
+                    break;
+                }
+            }
+        }
+    }
+
+    *outOfBouds1 = 0;
+    *outOfBouds2 = 0;
+    *outOfBouds3 = 0;
+
+    /* with two, one or no sensor, there is nothing to compare anymore
+     */
+    if(sensorNotActiveBinary)
+    {
+        // set outOfBounds for both tests
+        if(!sensorActive[0])
+            *outOfBouds1 = 1;
+
+        if(!sensorActive[1])
+            *outOfBouds2 = 1;
+
+        if(!sensorActive[2])
+            *outOfBouds3 = 1;
+
+        return;
+    }
+    else
+    {
+        uint8_t sensor_id_ordered[3];
+        uint8_t difference[2];
+
+        if((receiveHUD[boolHUDdata].sensor_ppo2_cbar[1]) > (receiveHUD[boolHUDdata].sensor_ppo2_cbar[0]))
+        {
+            sensor_id_ordered[0] = 0;
+            sensor_id_ordered[1] = 1;
+        }
+        else
+        {
+            sensor_id_ordered[0] = 1;
+            sensor_id_ordered[1] = 0;
+        }
+        if(receiveHUD[boolHUDdata].sensor_ppo2_cbar[2] > receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]])
+        {
+            sensor_id_ordered[2] = 2;
+        }
+        else
+        {
+            sensor_id_ordered[2] = sensor_id_ordered[1];
+            if(receiveHUD[boolHUDdata].sensor_ppo2_cbar[2] > receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[0]])
+            {
+                sensor_id_ordered[1] = 2;
+            }
+            else
+            {
+                sensor_id_ordered[1] = sensor_id_ordered[0];
+                sensor_id_ordered[0] = 2;
+            }
+        }
+
+        difference[0] = receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]]- receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[0]];
+        difference[1] = receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[2]]- receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]];
+
+        if((difference[0] > difference[1]) && (difference[0] > 15))
+        {
+            switch(sensor_id_ordered[0])
+            {
+            case 0:
+                *outOfBouds1 = 1;
+            break;
+            case 1:
+                *outOfBouds2 = 1;
+            break;
+            case 2:
+                *outOfBouds3 = 1;
+            break;
+            }
+        }
+        else
+        if((difference[0] < difference[1]) && (difference[1] > 15))
+        {
+            switch(sensor_id_ordered[2])
+            {
+            case 0:
+                *outOfBouds1 = 1;
+            break;
+            case 1:
+                *outOfBouds2 = 1;
+            break;
+            case 2:
+                *outOfBouds3 = 1;
+            break;
+            }
+        }
+    }
+}
+
+
+uint8_t get_ppO2SensorWeightedResult_cbar(void)
+{
+    int8_t sensorOutOfBound[3];
+    uint16_t result = 0;
+    uint8_t count = 0;
+
+    test_HUD_sensor_values_outOfBounds(&sensorOutOfBound[0], &sensorOutOfBound[1], &sensorOutOfBound[2]);
+
+    for(int i=0;i<3;i++)
+    {
+        if(!sensorOutOfBound[i])
+        {
+            result += receiveHUD[boolHUDdata].sensor_ppo2_cbar[i];
+            count++;
+        }
+    }
+    if(count == 0) // all sensors out of bounds!
+        return 0;
+    else
+        return (uint8_t)(result / count);
+}
+
+
+void tCCR_init(void)
+{
+    StartListeningToUART_HUD = 1;
+}
+
+
+ /* after 3 seconds without update from HUD
+    * data is considered old
+    */
+void tCCR_tick(void)
+{
+    if(count < 3 * 10)
+        count++;
+    else
+    {
+        data_old__lost_connection_to_HUD = 1;
+        if(count < 20 * 10)
+            count++;
+        else
+            tCCR_fallbackToFixedSetpoint();
+    }
+}
+
+
+void tCCR_restart(void)
+{
+    HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/
+}
+
+
+void tCCR_control(void)
+{
+    if((UartReadyHUD == RESET) && StartListeningToUART_HUD)
+    {
+            StartListeningToUART_HUD = 0;
+            HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/
+    }
+
+    if(UartReadyHUD == SET)
+    {
+            UartReadyHUD = RESET;
+
+            memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11);
+            receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]);
+            receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]);
+
+            uint16_t checksum = 0;
+
+            for(int i=0;i<13;i++)
+            {
+                checksum += receiveHUDraw[i];
+            }
+            if(checksum == receiveHUD[!boolHUDdata].checksum)
+            {
+                boolHUDdata = !boolHUDdata;
+                count = 0;
+                data_old__lost_connection_to_HUD = 0;
+            }
+            StartListeningToUART_HUD = 1;
+    }
+}
+
+#endif
+/* Private functions ---------------------------------------------------------*/
+
+void tCCR_fallbackToFixedSetpoint(void)
+{
+    if((stateUsed->mode == MODE_DIVE) && (stateUsed->diveSettings.diveMode == DIVEMODE_CCR) && (stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) && (stateUsed->diveSettings.fallbackOption))
+    {
+        uint8_t setpointCbar, actualGasID;
+        SDiveState *pState;
+
+        if(stateUsed == stateRealGetPointer())
+            pState = stateRealGetPointerWrite();
+        else
+            pState = stateSimGetPointerWrite();
+
+        setpointCbar = pState->diveSettings.setpoint[1].setpoint_cbar;
+        pState->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint;
+
+        actualGasID = pState->lifeData.actualGas.GasIdInSettings;
+        setActualGas_DM(&pState->lifeData,actualGasID,setpointCbar);
+
+        set_warning_fallback();
+    }
+}