Started a gui menuflow

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI BSP_DISCO_F429ZI

Files at this revision

API Documentation at this revision

Comitter:
ahaas92
Date:
Thu Jun 11 22:55:06 2020 +0000
Parent:
2:5828e6917e75
Commit message:
Init of gui structure ;

Changed in this revision

Monitoring.c Show diff for this revision Revisions of this file
Monitoring.txt Show annotated file Show diff for this revision Revisions of this file
Safety.c Show diff for this revision Revisions of this file
Safety.txt Show annotated file Show diff for this revision Revisions of this file
Screens.cpp Show annotated file Show diff for this revision Revisions of this file
Screens.h Show annotated file Show diff for this revision Revisions of this file
Touch.cpp Show annotated file Show diff for this revision Revisions of this file
Touch.h Show annotated file Show diff for this revision Revisions of this file
Ventilation.c Show diff for this revision Revisions of this file
Ventilation.txt Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
--- a/Monitoring.c	Tue Jun 09 22:57:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1375 +0,0 @@
-*********************************************************************/
-
-/* Includes ------------------------------------------------------------------*/
-#define EXTERN extern
-#include "SS.h"                   
-#include "main.h"                   
-#include "_ss_pwm.h"      
-#include "_SS_I2CX_Drivers.h"
-#include "_SS_I2CX_SDP600.h"
-#include "_SS_I2CX_X201641.h"
-#include "Ventilation.h"   
-#include "MotorTempTable.h"
-#include "_SS_FlowComputer.h"
-#include "_SS_TSI_4040.h"
-#include "_SS_Data_Logging.h"
-#include "_SS_OnOffActioner.h"
-#undef EXTERN
-
-#define INIT_VARIABLES
-#define EXTERN
-#include "Monitoring.h"           
-#undef  EXTERN
-#undef  INIT_VARIABLES
-  
-  
-// *********************** Register locations **********************************
-#define DMA_IFCR1    (*(volatile uint32_t *)0x40020004)
-#define DMA_CCR1     (*(volatile uint32_t *)0x40020008)
-#define DMA_CNTDR1   (*(volatile uint32_t *)0x4002000c)
-#define DMA_CPAR1    (*(volatile uint32_t *)0x40020010)
-#define DMA_CMAR1    (*(volatile uint32_t *)0x40020014)
-
-#define ADC1_SR      (*(volatile uint32_t *)0x40012400)
-#define ADC1_SQR1    (*(volatile uint32_t *)0x4001242C)
-#define ADC1_SQR2    (*(volatile uint32_t *)0x40012430)
-#define ADC1_SQR3    (*(volatile uint32_t *)0x40012434)
-#define ADC1_LTR     (*(volatile uint32_t *)0x40012428)
-#define ADC1_HTR     (*(volatile uint32_t *)0x40012424)
-#define ADC1_CR1     (*(volatile uint32_t *)0x40012404)
-#define ADC1_CR2     (*(volatile uint32_t *)0x40012408)
-
-
-// ************************* ADC CONFIGURATION CHANNELS ************************
-#define FREE_MEAS_CHANNEL             0
-#define PPROX_MEAS_CHANNEL            1
-#define CURRENT_MEAS_CHANNEL          2
-#define ALIM_24V_MEAS_CHANNEL         6
-#define TEMP_PHASE_A                  5
-#define TEMP_PHASE_B                  4
-#define TEMP_PHASE_C                  3
-
-// ********************* 24V ALARM MANAGEMENT **********************************
-#ifndef C_M3_DEVICETEST_TARGET
-
-#endif    
-
-
-
-// ************************ I2C SENSORS MANAGEMENT *****************************
-#ifndef C_M3_DEVICETEST_TARGET
-  #define       READING_NO_SENSOR               0
-  #define       READING_FLOW_SENSORS            1
-  //#define       READING_PRESSURE_SENSORS        2
-  #define       STOP_READING_FLOW_SENSORS       3
-  #define       START_READING_FLOW_SENSORS      4
-  #define       NUMBER_I2C_REBOOT               3
-  
-  #define       FLOW_SENSOR_READING             0
-  #define       FLOW_SENSOR_OK                  1
-  #define       FLOW_SENSOR_FAIL                2
-  static          u8            ucStatusSDP600=FLOW_SENSOR_READING;
-  static          u8            ucStatusX201641=FLOW_SENSOR_READING;
-  
-  static volatile u8            ucReadingFlowSensor=START_READING_FLOW_SENSORS;    // I2Cx sensor managment
-  static          u8            ucCounterFlowErrorMeasurement=0;
-  static          u16           uiTotalCounterFlowErrorMeasurement=0;
-
-  #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)  
-    #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
-      #define       SMOOTH_BLOWER_RAW_FLOW_COUNTER      50
-      static          u16           uiBlowerRAWFlowTemp[SMOOTH_BLOWER_RAW_FLOW_COUNTER];                  
-      static          u8            ucIndexBlowerRAWFlowSmooth=0;
-      
-      #define       BLOWER_RAW_FLOW_SAMPLES_NUMBER  200
-      static          u32           ulSumBlowerFlowRAWMes=0;
-      static          u16           uiBlowerRAWFlowSamplesCounter=BLOWER_RAW_FLOW_SAMPLES_NUMBER;
-    #endif
-    
-    #define       SMOOTH_BLOWER_FLOW_LARGE_COUNTER      75//100     // MUST BE HIGHER THAN SMOOTH_BLOWER_FLOW_SMALL_COUNTER
-    #define       SMOOTH_BLOWER_FLOW_SMALL_COUNTER      15      // MUST BE LOWER  THAN SMOOTH_BLOWER_FLOW_LARGE_COUNTER
-    static            int16_t       iTempBlowerFlowForSmallSmooth[SMOOTH_BLOWER_FLOW_SMALL_COUNTER];          
-    static            int16_t       iTempBlowerFlowForLargeSmooth[SMOOTH_BLOWER_FLOW_LARGE_COUNTER];          
-    static            u8            ucIndexSmallBlowerFlowSmooth=0;
-    static            u8            ucIndexLargeBlowerFlowSmooth=0;
-    
-    static            int16_t       idConductancedtSmooth[SMOOTH_BLOWER_FLOW_SMALL_COUNTER]; 
-  #endif  // (SDP600_USED_I2C1_BUS) || (X201641_USED_I2C1_BUS)  
-#endif    // C_M3_DEVICETEST_TARGET
-    
-    
-    
-// ****************** PROXIMAL PRESSURE SENSOR MANAGEMENT **********************
-#ifndef C_M3_DEVICETEST_TARGET
-  #define         SMOOTH_PPROX_PRESSURE_COUNTER   40
-  static  u8              ucIndexPproxPressureSmooth=0;  
-  static  u16             uiProximalPressureTemp[SMOOTH_PPROX_PRESSURE_COUNTER];
-#endif  // C_M3_DEVICETEST_TARGET
-  
-  
-  
-// ********************* MEASURES MANAGEMENT **********************************
-#ifndef C_M3_DEVICETEST_TARGET              
-  // ---- Current measurement
-  static  u32             ulSumCurrentADCMesFiltered=0;
-  static  u32             ulCounterADC_FilteredBlowerCurrentMes=0;
-  
-  // ---- Temperature measurement
-  static  u32             ulADCSumBlowerTemperature=0;
-  static  u16             uiTemperatureSamplesCounter=0;
-  
-  #ifdef TEMPERATURE_TRENDS
-    #ifdef  USE_FLOW_COMPUTER 
-      #define   FLOW_COMPUTER_CYCLE_DETECTION_TIMER                   10        // 100ms
-      static  u8              ucFlowComputerCycle=EXPIRATION_CYCLE;
-      static  u16             uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
-    #else
-      #define   TIME_OUT_TEMPERATURE_MEASUREMENT                      6000      // 60s
-      static  u16             uiTimeOutTemperatureMeasurement=0;
-    #endif  // #ifdef  USE_FLOW_COMPUTER 
-    static  u32             ulADCSumTemperaturePhaseA=0;
-    static  u16             uiADCTemperaturePhaseA;
-    static  u32             ulADCSumTemperaturePhaseB=0;
-    static  u16             uiADCTemperaturePhaseB;
-    static  u32             ulADCSumTemperaturePhaseC=0;
-    static  u16             uiADCTemperaturePhaseC;  
-  #endif
-    
-  // ---- Blower Speed measurment
-  static  u32             ulSumTachoTicks=0;
-  static  u32             ulCounterAverageMotorSpeed=0;
-    
-  // --- Blower current Bessel filter  
-  /*static  u16             uiCurrentADCMesFilteredPrev2;
-  static  u16             uiCurrentADCMesFilteredPrev1;  
-  static  u16             uiCurrentADCMesPrev2;
-  static  u16             uiCurrentADCMesPrev1;
-  static  u16             uiCurrentADCMesFiltered;*/
-
-  // --- Motor voltage
-  static  u32             ulSumADC_MotorVoltage;
-  static  u32             ulCounterADC_MotorVoltage;  
-  
-  // --- Temporary measurements
-  static  u16             uiPproxMax;
-  static  u16             uiVtiTemp;
-  static  u16             uiVteTemp;
-  static  u16             uiTiMesTemp;
-  static  u16             uiTeMesTemp;
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-  
-  
-#ifndef C_M3_DEVICETEST_TARGET  
-  static  u8              ucVentilationCycleCopy=INSPIRATION_CYCLE;
-  static  int32_t         lSumVti=0;
-  static  int32_t         lSumVte=0;
-  static  u8              ucCounterAlarmVteMin=0;
-  static  u8              ucCounterLPAlarm=0;
-#endif  // C_M3_DEVICETEST_TARGET  
-  
-  
-#define RCC_APB2RSTR (*(volatile uint32_t *)0x4002100c)
-
-  
-// ***************** Functions **********************************************
-int16_t ComputeFlowInLitersPerMin(u16 uFlowRAW, bool bPositiveFlow);
-void    ComputeBlowerPower(void);
-u16     ComputeTemperature(u16 uiADCMotorTemp, u16 *puiTempLUT, u16 uiTemperatureGain);
-
-
-/*******************************************************************************
-* Function Name  : ADC1_init
-* Description    : Init ADC1
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ADC1_init(void)
-{
-  // First perform De_init
-  DMA_CCR1 &= (uint32_t)(~0x1);  // channel 1 disable
-  DMA_CCR1 = 0; // Reset Channelx control register
-  DMA_CNTDR1 = 0; // Reset Channelx remaining bytes register
-  DMA_CPAR1 = 0; // Reset Channelx peripheral address register
-  DMA_CMAR1 = 0; // Reset Channelx memory address register
-  DMA_IFCR1 |= DMA_Channel1_IT_Mask; // Reset interrupt pending bits
-  // end de-init
-
-  // Initialise DMA #1
-  DMA_CPAR1 = (uint32_t)(ADC1_BASE + 0x4c);    // base adress of ADC1 ADC_DR register
-  
-  DMA_CMAR1 = (unsigned long)(&uiADC_Value[0]);
-  DMA_CNTDR1 = NUMBER_ADC_CONVERSION;   // numbers of data to be transfered
-  
-  DMA_CCR1 = (3<<12) + (1<<10) + (1<<8) + (1<<7) + (1<<5) /*+ (1<<1)*/; // very high priority, mem size 16 bits, periph size 16 bits, mem increase,/* circular enabled*/, /*transfer complete IT*/
-  DMA_CCR1 |= 1;  // channel 1 enable  
-  
-  
-  
-  // De-init of the ADC 1
-  RCC_APB2RSTR |= RCC_APB2Periph_ADC1;          // enable
-  RCC_APB2RSTR &= ~RCC_APB2Periph_ADC1;         // disable
-  // end De-init of the ADC 1
-      
-  // Select channels of the regular group
-  #ifdef TEMPERATURE_TRENDS  
-    ADC1_SQR1 = ((NUMBER_ADC_CONVERSION-1)<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;
-    ADC1_SQR2 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + TEMP_PHASE_C;  
-    ADC1_SQR3 = (TEMP_PHASE_B<<25) + (TEMP_PHASE_A<<20) + (FREE_MEAS_CHANNEL<<15) + (CURRENT_MEAS_CHANNEL<<10) + (ALIM_24V_MEAS_CHANNEL<<5) + PPROX_MEAS_CHANNEL;      
-  #else
-    ADC1_SQR1 = ((NUMBER_ADC_CONVERSION-1)<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;
-    ADC1_SQR2 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;  
-    ADC1_SQR3 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (CURRENT_MEAS_CHANNEL<<10) + (ALIM_24V_MEAS_CHANNEL<<5) + PPROX_MEAS_CHANNEL;      
-  #endif
-      
-  // 21 micros ADC conversion time
-  ADC1->SMPR2= (7<<27) + (7<<24) + (7<<21) + (7<<18) + (7<<15) + (7<<12) + (7<<9) + (7<<6) + (7<<3) + 7;      
-  ADC1->SMPR1= (7<<21) + (7<<18) + (7<<15) + (7<<12) + (7<<9) + (7<<6) + (7<<3) + 7;   
-  
-  ADC1_CR1  = (1<<8);                                                           // Scan mode enabled
-  ADC1_CR2  = (1<<8);                                                           // DMA mode enabled
-    
-  ADC1_CR2 |= 1;                                                                // start ADC1 - power-on
-
-  // Delay at least 1uSec for ADC calibration/stabilisation. See ADC documentation
-  // Stabilization time > 1uS for ADC, between power-on and start of conversion
-  // Give it 10uSecs just to be sure.   
-  Delay100NS(100);  
-  
-  // Calibration of ADC1
-  ADC1_CR2 |= (1<<3);                                                           // reset calibration registers
-  ADC1_CR2 |= (1<<2);                                                           // Enable calibration
-  while ((ADC1_CR2 & (1<<2)) == (1<<2));                                        // Wait end of calibration
-  
-  ADC1_CR2 |= 1;                                                                // start ADC1 - start conversions    
-}
-
-
-/*******************************************************************************
-* Function Name  : CheckAlimMotorVoltage
-* Description    : Check the voltage range of the 24V power supply
-* Input          : None
-* Output         : None
-* Return         : OPSTATUS_OK or OPSTATUS_FAIL
-*******************************************************************************/
-opstatus_t CheckAlimMotorVoltage(void)
-{
-  if (uiDCinADCMeas<271 || uiDCinADCMeas>2090)
-    return(OPSTATUS_FAIL);                        // <12V or >24V
-  return(OPSTATUS_OK);
-}
-
-
-/*******************************************************************************
-* Function Name  : Compute24VMeasure
-* Description    : Compute the 24V measure
-* Input          : None
-* Output         : None
-* Return         : OPSTATUS_OK or OPSTATUS_FAIL
-*******************************************************************************/
-#ifndef C_M3_DEVICETEST_TARGET
-void Compute24VMeasure(void)
-{
-  u32 ulTemp;
-  u16 uiADC_BlowerVoltage;
-  
-  if (bMemoStartVentilation==TRUE)
-    uiADC_BlowerVoltage=uiAverageADC_MotorVoltage;
-  else
-    uiADC_BlowerVoltage=uiDCinADCMeas;
-    
-  ulTemp=((u32)uiADC_BlowerVoltage*100)/1452;
-  ulTemp+=100;
-  uiTechnicalDataMes[MOTOR_VOLTAGE_TEC_MES]=(u16)ulTemp;
-  uiMotorVoltageMes=(u16)ulTemp;
-}
-#endif
-
-void GetFirstMotorVoltageReading(void)
-{
-  uiAverageADC_MotorVoltage=uiDCinADCMeas;
-}
-/*******************************************************************************
-* Function Name  : ComputeBlowerPower
-* Description    : Compute the power of the blower
-* Input          : None
-* Output         : None
-* Return         : OPSTATUS_OK or OPSTATUS_FAIL
-*******************************************************************************/
-void ComputeBlowerPower(void)
-{
-  uiTechnicalDataMes[MOTOR_POWER_TEC_MES]=((u32)uiMotorVoltageMes*uiBlowerCurrentMes)/10;
-}
-
-/*******************************************************************************
-* Function Name  : SpeedMeasurement
-* Description    : Return blower speed
-* Input          : Tacho counter
-* Output         : None
-* Return         : Blower speed in RPM
-*******************************************************************************/
-u16 SpeedMeasurement(u16 uiTachoCounter)
-{
-  u16 uiSpeedTemp=65500;
-    
-  if (uiTachoCounter>915)
-    uiSpeedTemp=(u16)(60000000UL/uiTachoCounter);        
-  
-  return(uiSpeedTemp);
-}
-
-
-/*******************************************************************************
-* Function Name  : ReadADCInputs
-* Description    : Read all ADC input (function calls every 1ms)
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/  
-void ReadADCInputs(void)
-{ 
-  //u32       ulTerm1, ulTerm2, ulTerm3, ulTerm4, ulTerm5;
-  
-  // ADC Pprox measurement
-  uiProximalPressureADCMes=uiADC_Value[ADC_PPROX_MES];   
-          
-  // ADC DCin measurement
-  uiDCinADCMeas=uiADC_Value[ADC_DCIN_MES];
-  
-  // ADC Blower current measurement
-  ComputeADCBlowerCurrent(FALSE);      
-  
-  // ADC Free measurement  
-  uiADCBlowerTemperatureMeas=uiADC_Value[ADC_FREE_MES];
-     
-  #ifdef TEMPERATURE_TRENDS
-  uiADCTemperaturePhaseA=uiADC_Value[ADC_TEMP_PHASE_A];
-  uiADCTemperaturePhaseB=uiADC_Value[ADC_TEMP_PHASE_B];
-  uiADCTemperaturePhaseC=uiADC_Value[ADC_TEMP_PHASE_C];
-  #endif
-  
-  // 2nd order Bessel Filter (Fcut-out=36Hz, sample rate=1KHz)
-  /*ulTerm1=(919UL*uiADCBlowerCurrent)>>6;
-  ulTerm2=(919UL*uiCurrentADCMesPrev1)>>5;
-  ulTerm3=(919UL*uiCurrentADCMesPrev2)>>6;
-  ulTerm4=(1427UL*uiCurrentADCMesFilteredPrev1)>>1;
-  ulTerm5=259UL*uiCurrentADCMesFilteredPrev2;
-  
-  uiCurrentADCMesFiltered=(ulTerm1+ulTerm2+ulTerm3+ulTerm4-ulTerm5)>>9;
-  uiCurrentADCMesFilteredPrev2=uiCurrentADCMesFilteredPrev1;
-  uiCurrentADCMesFilteredPrev1=uiCurrentADCMesFiltered;  
-  uiCurrentADCMesPrev2=uiCurrentADCMesPrev1;
-  uiCurrentADCMesPrev1=uiADCBlowerCurrent;*/
-  
-  
-  // 2nd order Bessel Filter (Fcut-out=150Hz, sample rate=1KHz)
-  /*ulTerm1=(1929UL*uiADCBlowerCurrent)>>1;
-  ulTerm2=(1929UL*uiCurrentADCMesPrev1);
-  ulTerm3=(1929UL*uiCurrentADCMesPrev2)>>1;
-  ulTerm4=(1095UL*uiCurrentADCMesFilteredPrev1)>>1;
-  ulTerm5=(2479UL*uiCurrentADCMesFilteredPrev2)>>3;
-  
-  uiCurrentADCMesFiltered=(ulTerm1+ulTerm2+ulTerm3+ulTerm4-ulTerm5)>>12;
-  uiCurrentADCMesFilteredPrev2=uiCurrentADCMesFilteredPrev1;
-  uiCurrentADCMesFilteredPrev1=uiCurrentADCMesFiltered;  
-  uiCurrentADCMesPrev2=uiCurrentADCMesPrev1;
-  uiCurrentADCMesPrev1=uiADCBlowerCurrent;*/
-  
-  // --- Start new conversions
-  ADC1->CR2 |= 1;    
-}
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : ComputeMeasurements
-* Description    : Compute different measures
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/  
-void ComputeMeasurements(void)
-{    
-  // ---------------------- Measure Current (A) ----------------------------
-  uiBlowerCurrentMes=ComputeBlowerCurrentInAmper(uiADCBlowerCurrent);
-      
-  // -------------------- Compute motor voltage (V) ------------------------
-  Compute24VMeasure();
-  ComputeBlowerPower();    
-  
-  // ---------------------- Others measurements ----------------------------
-  if (bMemoStartVentilation==TRUE)
-  {
-    // --- Motor speed (RPM) (every 10ms)
-    uiBlowerSpeedMes=SpeedMeasurement(uiTachoTimeTicks);  
-  }  
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-#ifdef TEMPERATURE_TRENDS  
-/*******************************************************************************
-* Function Name  : ComputeAverageOnMeasurements
-* Description    : Average differents mesures : MUST BE CALLED EVERY 10ms 
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/  
-void ComputeAverageOnMeasurements(void)
-{   
-  #ifdef  USE_FLOW_COMPUTER
-    // ----------- USE THE FLOW COMPUTER TO DETECT CYCLE ----------------
-    u16         uiDummy;
-    opstatus_t  opstatus;
-    
-    // Read new flow from flow computer every 10ms  
-    opstatus=SS_Xgetw(flc, &uiDummy);        
-    if (opstatus==OPSTATUS_OK)
-    {
-      // Update flow/pressure displayed
-      uiBlowerFlow=iFlowFromFlowComputer*10;
-      uiPoutPressureMes=uiPressureFromFlowComputer;
-              
-      // Comm with flow computer OK !!    
-      #ifdef  DATA_LOGGING
-      if (bRecordTemperatureTrendsAllowed==FALSE)
-      {
-        bRecordTemperatureTrendsAllowed=TRUE;
-        uiTrendsSampleTime=RECORD_TRENDS_SAMPLE_TIME;
-      }
-      #endif  // DATA_LOGGING
-      
-      // inspiration/expiration cycle detection
-      if (ucFlowComputerCycle==EXPIRATION_CYCLE)
-      {
-        // Inspiration detection
-        if (iFlowFromFlowComputer>50) // 5l/min
-        {
-          uiFlowComputerCycleModificationTimer--;
-          if (uiFlowComputerCycleModificationTimer==0)
-          {
-            ucFlowComputerCycle=INSPIRATION_CYCLE;
-            
-            // Compute temperature of the previous inspiratory cycle
-            if (uiTemperatureSamplesCounter!=0)
-            {
-              uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);           
-              uiADCAverageTemperaturePhaseA=ulADCSumTemperaturePhaseA/uiTemperatureSamplesCounter;
-              uiADCAverageTemperaturePhaseB=ulADCSumTemperaturePhaseB/uiTemperatureSamplesCounter;
-              uiADCAverageTemperaturePhaseC=ulADCSumTemperaturePhaseC/uiTemperatureSamplesCounter;          
-            }
-            ulADCSumBlowerTemperature=0;
-            ulADCSumTemperaturePhaseA=0;
-            ulADCSumTemperaturePhaseB=0;
-            ulADCSumTemperaturePhaseC=0;
-            uiTemperatureSamplesCounter=0;
-          }
-        }
-        else
-          uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
-      }
-      else 
-      {
-        // Record temperature as long as the flow is positive
-        if (iFlowFromFlowComputer>(-10)) // >-1l/min
-        {
-          ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
-          ulADCSumTemperaturePhaseA+=uiADCTemperaturePhaseA;
-          ulADCSumTemperaturePhaseB+=uiADCTemperaturePhaseB;
-          ulADCSumTemperaturePhaseC+=uiADCTemperaturePhaseC;
-          uiTemperatureSamplesCounter++;
-        }
-        
-        // Expiration detection
-        if (iFlowFromFlowComputer<(-50)) // <-5l/min
-        {
-          uiFlowComputerCycleModificationTimer--;
-          if (uiFlowComputerCycleModificationTimer==0)
-            ucFlowComputerCycle=EXPIRATION_CYCLE;
-        }
-        else
-          uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
-      }
-    }
-    else if (opstatus==OPSTATUS_FAIL)
-    {
-      // Comm Failure with flow computer => no data recorded
-      uiBlowerFlow=0;
-      uiPoutPressureMes=0;
-      
-      #ifdef  DATA_LOGGING
-      bRecordTemperatureTrendsAllowed=FALSE;
-      #endif     
-      uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=0;
-    }       
-  #else
-    // ----------- USE THE 24V MEASURE TO DETECT CYCLE ----------------        
-    if (uiDCinADCMeas>500)
-    {
-      // Inspiration
-      ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
-      ulADCSumTemperaturePhaseA+=uiADCTemperaturePhaseA;
-      ulADCSumTemperaturePhaseB+=uiADCTemperaturePhaseB;
-      ulADCSumTemperaturePhaseC+=uiADCTemperaturePhaseC;
-      uiTemperatureSamplesCounter++;
-      uiTimeOutTemperatureMeasurement=TIME_OUT_TEMPERATURE_MEASUREMENT;
-      #ifdef  DATA_LOGGING
-      bRecordTemperatureTrendsAllowed=TRUE;
-      #endif
-    }
-    else if (uiTimeOutTemperatureMeasurement!=0)
-    {
-      // Expiration
-      uiTimeOutTemperatureMeasurement--;
-      if (uiTemperatureSamplesCounter!=0)
-      {
-        uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);           
-        uiADCAverageTemperaturePhaseA=ulADCSumTemperaturePhaseA/uiTemperatureSamplesCounter;
-        uiADCAverageTemperaturePhaseB=ulADCSumTemperaturePhaseB/uiTemperatureSamplesCounter;
-        uiADCAverageTemperaturePhaseC=ulADCSumTemperaturePhaseC/uiTemperatureSamplesCounter;          
-      }
-      ulADCSumBlowerTemperature=0;
-      ulADCSumTemperaturePhaseA=0;
-      ulADCSumTemperaturePhaseB=0;
-      ulADCSumTemperaturePhaseC=0;
-      uiTemperatureSamplesCounter=0;           
-    }  
-    else
-    {
-      uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=0;
-      
-      ulADCSumBlowerTemperature=0;
-      ulADCSumTemperaturePhaseA=0;
-      ulADCSumTemperaturePhaseB=0;
-      ulADCSumTemperaturePhaseC=0;
-      uiTemperatureSamplesCounter=0;   
-      
-      #ifdef  DATA_LOGGING
-      bRecordTemperatureTrendsAllowed=FALSE;
-      #endif            
-    }
-  #endif  // #ifdef  USE_FLOW_COMPUTER      
-}
-#endif  // #ifdef TEMPERATURE_TRENDS     
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-/*******************************************************************************
-* Function Name  : ComputeADCBlowerCurrent
-* Description    : Compute the average current during a PWM cycle (20micros)
-* Input          : bRecordCurrentOffset
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ComputeADCBlowerCurrent(bool bRecordCurrentOffset) 
-{                       
-  if (bRecordCurrentOffset==TRUE)
-  {        
-    uiADCOffsetBlowerCurrent=uiADCBlowerCurrent=uiADC_Value[ADC_CURRENT_MES];    
-  }
-  else
-  {    
-    uiADCBlowerCurrent=uiADC_Value[ADC_CURRENT_MES];              
-  }
-}
-
-
-/*******************************************************************************
-* Function Name  : ComputeBlowerCurrentInAmper
-* Description    : Return blower current value in cAmper (ex: 100=1.00A)
-* Input          : ADC value
-* Output         : None
-* Return         : Blower current in cAmper (ex: 100=1.00A)
-*******************************************************************************/
-int16_t ComputeBlowerCurrentInAmper(u16 uiADCBlowerCurrentLocal)
-{
-  int32_t lTempValue;  
-  
-  // Computation using MOT_CUR_MEAS2
-  lTempValue=(int32_t)uiADCBlowerCurrentLocal-(int32_t)uiADCOffsetBlowerCurrent;
-  lTempValue*=1000;
-  lTempValue/=uiTechnicalDataSet[GAIN_BLOWER_CURRENT_TEC];
-  return(lTempValue);  
-}
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : LaunchFlowReadingOnI2CBus
-* Description    : Open and Read the flow sensor(s) on the I2C bus
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void LaunchFlowReadingOnI2CBus(void)
-{
-  opstatus_t  byOpStatus;
-  u16         uiSensorErr;
-  
-  if (fOpenI2C1SDP600Sensors==FALSE  || fOpenI2C2SDP600Sensors==FALSE   ||
-      fOpenI2C1X201641Sensors==FALSE || fOpenI2C2X201641Sensors==FALSE)
-  {        
-    byOpStatus=SS_Xopen(I2C_SDP600);
-    if (byOpStatus==OPSTATUS_FAIL)
-      uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;     
-    
-    byOpStatus=SS_Xopen(I2C_X201641);
-    if (byOpStatus==OPSTATUS_FAIL)    
-      uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;     
-            
-    ucReadingFlowSensor=STOP_READING_FLOW_SENSORS;
-  }
-  else if (ucReadingFlowSensor==STOP_READING_FLOW_SENSORS)
-  {
-    ucReadingFlowSensor=START_READING_FLOW_SENSORS;
-  }
-  else if (ucReadingFlowSensor==READING_FLOW_SENSORS)
-  {            
-    // Reading SDP600 Flow sensors
-    if (ucStatusSDP600==FLOW_SENSOR_READING)
-    {
-      byOpStatus=SS_Xgetw(I2C_SDP600, &uiSensorErr);    
-      if (byOpStatus==OPSTATUS_OK)                  
-        ucStatusSDP600=FLOW_SENSOR_OK;          
-      else if (byOpStatus==OPSTATUS_FAIL)
-        ucStatusSDP600=FLOW_SENSOR_FAIL;
-    }
-    
-    // Reading X201641 Flow sensors
-    if (ucStatusX201641==FLOW_SENSOR_READING)
-    {
-      byOpStatus=SS_Xgetw(I2C_X201641, &uiSensorErr);    
-      if (byOpStatus==OPSTATUS_OK)            
-        ucStatusX201641=FLOW_SENSOR_OK;          
-      else if (byOpStatus==OPSTATUS_FAIL)          
-        ucStatusX201641=FLOW_SENSOR_FAIL;          
-    }
-    
-    // End of flow measurement?
-    if (ucStatusSDP600!=FLOW_SENSOR_READING && ucStatusX201641!=FLOW_SENSOR_READING)
-    {                              
-      if (ucStatusSDP600==FLOW_SENSOR_OK && ucStatusX201641==FLOW_SENSOR_OK)
-      {      
-        ucCounterFlowErrorMeasurement=0; 
-        #ifdef TIME_MEASUREMENT
-        GPIOB->BRR = GPIO_Pin_5;
-        #endif
-      }
-      else
-      {
-        // Error counters
-        uiTotalCounterFlowErrorMeasurement++;
-        ucCounterFlowErrorMeasurement++;
-        if (ucCounterFlowErrorMeasurement>=NUMBER_I2C_REBOOT)      
-        {
-          //ulErrorCounter|=uiSensorErr;                                                      
-          uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;
-        }
-      }
-      
-      // Next Sensors to measure
-      ucReadingFlowSensor=READING_NO_SENSOR;
-      ucStatusSDP600=FLOW_SENSOR_READING;
-      ucStatusX201641=FLOW_SENSOR_READING;
-    }
-  }
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : ComputeFlowMeasurement
-* Description    : Conpute inspiratory and erxpiratory flow measurements
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ComputeFlowMeasurement(void)
-{
-  #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)
-  int32_t     lValue;
-  u16         uiValue;
-  #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
-    u32         ulValue;
-  #endif
-  #endif
-  
-  if (ucReadingFlowSensor==START_READING_FLOW_SENSORS)
-  {
-    ucReadingFlowSensor=READING_FLOW_SENSORS;
-  }
-  else if (ucReadingFlowSensor==READING_NO_SENSOR)
-  {    
-    ucReadingFlowSensor=READING_FLOW_SENSORS;  
-  
-    // **** Reading of the Inspiratory RAW Flow
-    #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)          
-      #ifdef SDP600_USED_I2C1_BUS          
-        SDP600_ReadADCFlowValue(I2C1, SDP600_BLOWER_FLOW_SENSOR, &uiValue);  
-      #endif
-      #ifdef X201641_USED_I2C1_BUS          
-        X201641_ReadADCFlowValue(I2C1, X201641_BLOWER_FLOW_SENSOR, &uiValue);  
-      #endif
-      if (uiValue==uiTechnicalDataSet[FLOWI_OFFSET_TEC])
-      {
-        uiBlowerFlowRAWMes=0;
-        iBlowerFlowMes=0;
-      }
-      else if (uiValue>uiTechnicalDataSet[FLOWI_OFFSET_TEC])
-      {
-        uiBlowerFlowRAWMes=uiValue-uiTechnicalDataSet[FLOWI_OFFSET_TEC];
-        iBlowerFlowMes=ComputeFlowInLitersPerMin(uiBlowerFlowRAWMes, FALSE);
-      }
-      else
-      {
-        uiBlowerFlowRAWMes=uiTechnicalDataSet[FLOWI_OFFSET_TEC]-uiValue;
-        iBlowerFlowMes=ComputeFlowInLitersPerMin(uiBlowerFlowRAWMes, TRUE);
-      }
-        
-      // Smoothing RWA data signals
-      #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
-      uiBlowerRAWFlowTemp[ucIndexBlowerRAWFlowSmooth]=uiBlowerFlowRAWMes;
-      ulValue=0;
-      for (uiValue=0; uiValue<SMOOTH_BLOWER_RAW_FLOW_COUNTER; uiValue++)          
-          ulValue+=uiBlowerRAWFlowTemp[uiValue];  
-      uiBlowerFlowRAWSmoothingMes=ulValue/SMOOTH_BLOWER_RAW_FLOW_COUNTER;                          
-      ucIndexBlowerRAWFlowSmooth++;
-      if (ucIndexBlowerRAWFlowSmooth>=SMOOTH_BLOWER_RAW_FLOW_COUNTER)
-        ucIndexBlowerRAWFlowSmooth=0;
-         
-      // Average of the RAW data signal      
-      ulSumBlowerFlowRAWMes+=uiBlowerFlowRAWSmoothingMes;
-      uiBlowerRAWFlowSamplesCounter--;
-      if (uiBlowerRAWFlowSamplesCounter==0)
-        {           
-        uiAverageBlowerFlowRAWMes=ulSumBlowerFlowRAWMes/BLOWER_RAW_FLOW_SAMPLES_NUMBER;
-        ulSumBlowerFlowRAWMes=0;
-        uiBlowerRAWFlowSamplesCounter=BLOWER_RAW_FLOW_SAMPLES_NUMBER;
-        }
-      #endif  // DISPLAY_AVERAGE_BLOWER_RAW_FLOW
-    
-    
-    // **** Reading of the Inspiratory Flow in l/min
-    /*#ifdef SDP600_USED_I2C1_BUS
-      SDP600_CalculFlowValue(I2C1, SDP600_BLOWER_FLOW_SENSOR, &iBlowerFlowMes);                          
-    #endif
-    #ifdef X201641_USED_I2C1_BUS  
-      X201641_CalculFlowValue(I2C1, X201641_BLOWER_FLOW_SENSOR, &iBlowerFlowMes);                          
-    #endif*/
-    iTempBlowerFlowForSmallSmooth[ucIndexSmallBlowerFlowSmooth]=iBlowerFlowMes;        
-    iTempBlowerFlowForLargeSmooth[ucIndexLargeBlowerFlowSmooth]=iBlowerFlowMes;        
-           
-    // Small Smoothing of the inspiratory flow signal
-    lValue=0;
-    for (uiValue=0; uiValue<SMOOTH_BLOWER_FLOW_SMALL_COUNTER; uiValue++)          
-        lValue+=iTempBlowerFlowForSmallSmooth[uiValue];          
-    iBlowerFlowSmoothingMes=lValue/(int16_t)SMOOTH_BLOWER_FLOW_SMALL_COUNTER;        
-    ucIndexSmallBlowerFlowSmooth++;
-    if (ucIndexSmallBlowerFlowSmooth>=SMOOTH_BLOWER_FLOW_SMALL_COUNTER)
-      ucIndexSmallBlowerFlowSmooth=0;
-    
-    // Large Smoothing of the inspiratory flow signal
-    lValue=0;
-    for (uiValue=0; uiValue<SMOOTH_BLOWER_FLOW_LARGE_COUNTER; uiValue++)          
-        lValue+=iTempBlowerFlowForLargeSmooth[uiValue];          
-    iBlowerFlowSmoothingMesForTrigger=lValue/(int16_t)SMOOTH_BLOWER_FLOW_LARGE_COUNTER;            
-    ucIndexLargeBlowerFlowSmooth++;
-    if (ucIndexLargeBlowerFlowSmooth>=SMOOTH_BLOWER_FLOW_LARGE_COUNTER)
-      ucIndexLargeBlowerFlowSmooth=0; 
-    
-    // Flow for Optima Comm 
-    uiBlowerFlow=iBlowerFlowMes;
-    uiBlowerFlowSmoothingMes=iBlowerFlowSmoothingMes;
-    uiBlowerFlowTriggerMes=iBlowerFlowSmoothingMesForTrigger;
-    #endif  // (SDP600_USED_I2C1_BUS) || (X201641_USED_I2C1_BUS)
-  }
-  
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-double powApprox(double a, double x)
-{
-    union
-    {
-        double d;
-        int A[2];
-    } Z = { a };
-    Z.A[1] = (int)(x * (Z.A[1] - 1072632447) + 1072632447);
-    Z.A[0] = 0;
-    return Z.d;
-}
-/*******************************************************************************
-* Function Name  : ComputeConductance
-* Description    : Compute Conductance
-* Input          : Pressure, Flow
-* Output         : Conductance
-* Return         : None
-*******************************************************************************/
-float prevConductance = 0.0f;
-u8 bufferIndex = 0;
-bool filled = FALSE;
-int16_t littleSum = 0;
-
-void ComputeConductance(void)
-{
-  float pressure = iProximalPressureMes/10.0f;
-  float flow = iBlowerFlowSmoothingMes/100.0f/60.0f;
-  float density = 1.225f;
-  float viscosity = 0.00018f;
-  float calcConductance = 0.0f;
-  
-  if(pressure != 0)
-  {
-          calcConductance  = (100000)*((powApprox((flow*0.001f),1.75)*powApprox(density,0.75)*powApprox(viscosity,0.25)/(pressure / 10.0f)* 98.0638f));
-          calcConductance  = calcConductance * 1000.0f;          
-          if(calcConductance < 60000 && calcConductance > -60000)
-          {
-                  uiConductanceCalc = (int16_t)calcConductance;
-          }         
-  }
-//  int16_t tempValue = idConductancedtSmooth[bufferIndex];
-//  idConductancedtSmooth[bufferIndex]= (int16_t)(calcConductance - prevConductance);//1000;
-//  littleSum += idConductancedtSmooth[bufferIndex];
-//  bufferIndex++;
-//  if(bufferIndex > SMOOTH_BLOWER_FLOW_LARGE_COUNTER)
-//  {
-//    bufferIndex = 0;
-//    if(!filled)
-//    {
-//      filled = TRUE;
-//    }
-//  }
-//  
-//  if(filled)
-//  {
-//    littleSum -= tempValue;    
-//    uidConductanceCalcdt = littleSum/SMOOTH_BLOWER_FLOW_LARGE_COUNTER;
-//  }
-  uidConductanceCalcdt = (int16_t)(calcConductance - prevConductance);
-  prevConductance  = calcConductance;
-}
-/*******************************************************************************
-* Function Name  : ComputeProximalPressureMeasurements
-* Description    : Compute Proximal pressure measurements
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ComputeProximalPressureMeasurements(void)
-{
-  u32 ulValue;
-  u16 uiValue;
-    
-  iProximalPressureMes=((100L*((int16_t)uiProximalPressureADCMes-(int16_t)uiTechnicalDataSet[PPROX_OFFSET_TEC]))/(int16_t)uiTechnicalDataSet[PPROX_GAIN_TEC]);                  
-  if (iProximalPressureMes>0)
-    uiProximalPressureMes=(u16)iProximalPressureMes;
-  else
-    uiProximalPressureMes=0; 
-  uiNegativeProximalPressureMes=iProximalPressureMes;
-  
-  // Smoothing proximal pressure
-  uiProximalPressureTemp[ucIndexPproxPressureSmooth]=uiProximalPressureMes;  
-  ulValue=0;
-  for (uiValue=0; uiValue<SMOOTH_PPROX_PRESSURE_COUNTER; uiValue++)          
-      ulValue+=uiProximalPressureTemp[uiValue];          
-  uiProximalPressureSmoothingMes=ulValue/SMOOTH_PPROX_PRESSURE_COUNTER;
-  
-  ucIndexPproxPressureSmooth++;
-  if (ucIndexPproxPressureSmooth>=SMOOTH_PPROX_PRESSURE_COUNTER)
-    ucIndexPproxPressureSmooth=0;                             
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : ComputeOffsetProximalPressureSensor
-* Description    : Compute offset of the proximal pressure sensor
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ComputeOffsetProximalPressureSensor(void)
-{
-  u32 ulOffsetSum=0;
-  u16 i;
-  
-  for (i=0; i<64; i++)
-  {
-    ulOffsetSum+=uiADC_Value[ADC_PPROX_MES];
-    uiTempoSysTick=5;
-    while (uiTempoSysTick!=0){}
-  }
-  uiTechnicalDataSet[PPROX_OFFSET_TEC]=ulOffsetSum>>6;    
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : VentilationMonitoringAndAlarms
-* Description    : Compute measurements and alarms during ventilation
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void VentilationMonitoringAndAlarms(void)
-{
-  u16 uiTotalTimeMes;
-  
-  if (bMemoStartVentilation==TRUE && uiTechnicalDataSet[DEVICE_MODE_TEC]==VENTILATION_MODE)
-  {    
-    if (ucVentilationCycle==INSPIRATION_CYCLE)
-    {
-      // ***************** INSPIRATION ******************
-      if (ucVentilationCycleCopy==EXPIRATION_CYCLE)
-      {
-        // --- Beginning of inspiration
-        ucVentilationCycleCopy=INSPIRATION_CYCLE;
-        SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_ON);
-        
-        // Update Vte measurement
-        uiVentilationMeasures[VTE_MES]=uiVteTemp;
-        
-        // Update Te measurement
-        uiVentilationMeasures[TE_MES]=uiTeMesTemp;
-       
-        // Update Average ADC Motor Voltage
-        if (ulCounterADC_MotorVoltage!=0)
-          uiAverageADC_MotorVoltage=ulSumADC_MotorVoltage/ulCounterADC_MotorVoltage;
-        
-        // Update Current measurement
-        if (ulCounterADC_FilteredBlowerCurrentMes!=0)
-          uiBreathBlowerCurrentMes=ComputeBlowerCurrentInAmper(ulSumCurrentADCMesFiltered/ulCounterADC_FilteredBlowerCurrentMes);
-        ulSumCurrentADCMesFiltered=0; ulCounterADC_FilteredBlowerCurrentMes=0;
-        
-        // Update average blower speed
-        if (ulCounterAverageMotorSpeed!=0)
-          uiAverageBlowerSpeedMes=SpeedMeasurement(ulSumTachoTicks/ulCounterAverageMotorSpeed);
-        ulSumTachoTicks=0;    
-        ulCounterAverageMotorSpeed=0;
-
-        // Update average motor temperature during inspiration        
-        if (uiTemperatureSamplesCounter!=0)
-        {          
-            uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);          
-            if (uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]>890)
-              uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_TEMPERATURE_ALARM_MASK;
-            else if (uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]<810)
-              uiFlagsAlarm[ALARM_FLAGS2]&=(~MOTOR_TEMPERATURE_ALARM_MASK);
-        }
-        ulADCSumBlowerTemperature=0; uiTemperatureSamplesCounter=0;
-                        
-        // --- Pmax=0
-        uiPproxMax=0;
-                        
-        // --- Vti=0
-        lSumVti=0;
-        uiRecordVtiMes=uiVentilationMeasures[VTI_MES];        
-        
-        // --- Dislay Breath rate
-        uiTotalTimeMes=uiVentilationMeasures[TI_MES]+uiVentilationMeasures[TE_MES];
-        if (uiTotalTimeMes>0)
-          uiVentilationMeasures[BREATH_RATE_MES]=600000/uiTotalTimeMes;
-        
-        // --- Ti=0
-        uiTiMesTemp=0;
-        
-        // --- Max flow
-        iBlowerFlowSmoothingMaxMes=0;
-                        
-        // --- Alarm Vte Min
-        if (uiVentilationMeasures[VTE_MES]<uiVentilationSet[VTE_MIN_ALARM_SET] && enVentilationMode!=CPAP_MODE)
-        {
-          ucCounterAlarmVteMin++;
-          if (ucCounterAlarmVteMin>=5)
-          {
-            ucCounterAlarmVteMin=5;
-            uiFlagsAlarm[ALARM_FLAGS1]|=LOW_VTE_ALARM_MASK;
-          }
-        }
-        else
-        {
-          ucCounterAlarmVteMin=0;
-          uiFlagsAlarm[ALARM_FLAGS1]&=(~LOW_VTE_ALARM_MASK);
-        }
-      }
-      else //if (ucVentilationCycle==EXPIRATION_CYCLE)
-      {
-        // --- During inspiration
-        
-        // --- Motor Speed
-        ulSumTachoTicks+=uiTachoTimeTicks;    
-        ulCounterAverageMotorSpeed++;
-        
-        // --- Blower Current
-        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
-        ulCounterADC_FilteredBlowerCurrentMes++;
-        
-        // --- Inc Pmax
-        if (uiProximalPressureMes>uiPproxMax)
-          uiPproxMax=uiProximalPressureMes;
-        
-        // --- Inc max flow
-        if (iBlowerFlowSmoothingMes>iBlowerFlowSmoothingMaxMes)
-          iBlowerFlowSmoothingMaxMes=iBlowerFlowSmoothingMes;
-        
-        // --- Inc Vti
-        if (iBlowerFlowMes>30)
-          lSumVti+=iBlowerFlowMes;
-        uiVtiTemp=(u32)lSumVti/6000;       
-        
-        // --- Inc Ti
-        uiTiMesTemp++;
-
-        // --- Motor temperature        
-        ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
-        uiTemperatureSamplesCounter++;
-        
-        // --- Alarm Pmax
-        if (uiProximalPressureMes>uiVentilationSet[HIGH_PRESSURE_ALARM_SET] && enVentilationMode!=CPAP_MODE)
-        {
-          uiFlagsAlarm[ALARM_FLAGS1]|=HIGH_PRESSURE_ALARM_MASK;
-          fAlarmPmax=TRUE;          
-        }
-                                
-        // --- Alarm Vti Max
-        if ((uiVtiTemp>uiVentilationSet[VTI_MAX_ALARM_SET] && enVentilationMode==PS_MODE)   ||
-            (uiVtiTemp>uiVentilationSet[VTI_MAX_ALARM_SET] && enVentilationMode==APCV_MODE))
-        {
-          uiFlagsAlarm[ALARM_FLAGS1]|=HIGH_VTI_ALARM_MASK;
-          fAlarmVtiMax=TRUE;
-        }
-      }
-    }
-    else
-    {
-      // ***************** EXPIRATION ******************
-      if (ucVentilationCycleCopy==INSPIRATION_CYCLE)
-      {
-        // --- Beginning of Expiration
-        ucVentilationCycleCopy=EXPIRATION_CYCLE;
-        SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_OFF);
-        
-        // Update Pprox max measurement
-        uiVentilationMeasures[PPROX_MAX_MES]=uiPproxMax;
-          
-        // Update Vti measurement
-        uiVentilationMeasures[VTI_MES]=uiVtiTemp;
-        
-        // Update Ti measurement
-        uiVentilationMeasures[TI_MES]=uiTiMesTemp;
-        
-        // --- Motor Speed
-        ulSumTachoTicks+=uiTachoTimeTicks;    
-        ulCounterAverageMotorSpeed++;
-        
-        // --- Blower Current
-        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
-        ulCounterADC_FilteredBlowerCurrentMes++;
-        
-        // --- Vte=0
-        lSumVte=0;
-        
-        // --- Te=0
-        uiTeMesTemp=0;      
-        
-        // --- Alarm Low Pressure
-        if ((uiVentilationMeasures[PPROX_MAX_MES]<(uiVentilationSet[PS_SET]-5) && enVentilationMode==PS_MODE)   ||
-            (uiVentilationMeasures[PPROX_MAX_MES]<(uiVentilationSet[PI_SET]-5) && enVentilationMode==APCV_MODE) ||
-            (uiVentilationMeasures[PPROX_MAX_MES]<uiVentilationSet[LOW_PRESSURE_ALARM_SET] && enVentilationMode==AVC_MODE))
-        { 
-          ucCounterLPAlarm++;
-          if (ucCounterLPAlarm>=4)
-          {
-            ucCounterLPAlarm=4;
-            uiFlagsAlarm[ALARM_FLAGS1]|=LOW_PRESSURE_ALARM_MASK;
-          }
-        }
-        else
-        {
-          ucCounterLPAlarm=0;
-          uiFlagsAlarm[ALARM_FLAGS1]&=(~LOW_PRESSURE_ALARM_MASK);
-        }
-        
-        // --- Clear Alarm High pressure        
-        if (fAlarmPmax==FALSE)
-          uiFlagsAlarm[ALARM_FLAGS1]&=(~HIGH_PRESSURE_ALARM_MASK);
-        fAlarmPmax=FALSE;
-        
-        // --- Clear Alarm Vti Max
-        if (fAlarmVtiMax==FALSE)
-          uiFlagsAlarm[ALARM_FLAGS1]&=(~HIGH_VTI_ALARM_MASK);
-        fAlarmVtiMax=FALSE;
-      }
-      else
-      {
-        // --- During Expiration
-        
-        // --- Motor Speed
-        ulSumTachoTicks+=uiTachoTimeTicks;    
-        ulCounterAverageMotorSpeed++;
-        
-        // --- Blower Current
-        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
-        ulCounterADC_FilteredBlowerCurrentMes++;
-        
-        // --- Inc Vte
-        if (iBlowerFlowMes<(-30))
-          lSumVte+=iBlowerFlowMes;
-        if (lSumVte<0)
-          uiVteTemp=(u32)(lSumVte/(-6000));
-        else
-          uiVteTemp=0;
-        
-        // --- Inc Te
-        uiTeMesTemp++;
-        if (uiTeMesTemp>60000) uiTeMesTemp=60000;
-        
-        // --- Average motor voltage
-        if (uiTeMesTemp==100)
-        {
-          ulSumADC_MotorVoltage=0;
-          ulCounterADC_MotorVoltage=0;
-        }
-        else if (uiTeMesTemp>100)
-        {
-          ulSumADC_MotorVoltage+=uiDCinADCMeas;
-          ulCounterADC_MotorVoltage++;
-        }
-      }
-    }
-  } 
-  else // if (bMemoStartVentilation==TRUE && uiTechnicalDataSet[DEVICE_MODE_TEC]==VENTILATION_MODE) 
-  {
-    #ifndef TEMPERATURE_TRENDS
-    uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(uiADCBlowerTemperatureMeas);
-    #endif
-  }
-}
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-#ifndef C_M3_DEVICETEST_TARGET
-/*******************************************************************************
-* Function Name  : ClearVentilationAlarm
-* Description    : Clear all ventilation Alarms
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ClearAllVentilationAlarms(void)
-{
-  u8    i;
-  u8    ucAlarmFlag;
-  
-  for (i=0; i<SIZE_BLOWER_ALARM; i++)
-  {    
-    ucAlarmFlag=stBlowerAlarmStatus[i].ucAlarmFlag;
-    if (stBlowerAlarmStatus[i].bVentilationAlarm==TRUE && (ucAlarmFlag==ALARM_FLAGS1 || ucAlarmFlag==ALARM_FLAGS2))
-      uiFlagsAlarm[ucAlarmFlag]&=(~stBlowerAlarmStatus[i].uiAlarmMask);
-  }
-}
-
-                   
-/*******************************************************************************
-* Function Name  : ClearAlarm
-* Description    : Clear a specific alarm
-* Input          : Mask of the alarm
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ClearAlarm(u8 ucAlarmFlag, u16 uiMask)
-{ 
-  uiFlagsAlarm[ucAlarmFlag]&=(~uiMask);
-}
-
-                   
-/*******************************************************************************
-* Function Name  : ClearAllMeasures
-* Description    : Clear all ventilation measures
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ClearAllMeasures(void)
-{
-  u8  i;
-  
-  // Reset measures except alarms
-  for (i=0; i<SIZE_LRM_GROUP; i++)
-  {
-    if (i!=ALARM_ID1_MES && i!=ALARM_ID2_MES)// && i!=ALARM_ID3_MES && i!=ALARM_ID4_MES)      
-      uiVentilationMeasures[i]=0;
-  }  
-  
-  // Reset others measures
-  uiBlowerSpeedMes=0;             uiAverageBlowerSpeedMes=0;      // Speed=0 RPM
-  ulSumTachoTicks=0;              ulCounterAverageMotorSpeed=0;
-  uiBreathBlowerCurrentMes=0;                                   // Blower current=0 A
-  ulSumCurrentADCMesFiltered=0;   ulCounterADC_FilteredBlowerCurrentMes=0;
-  bDisplayInspiratoryTrigger=FALSE;    
-  #ifdef  MOTOR_LIFE_TESTING
-    uiAverateMotorTempMes=0;
-  #endif  // #ifdef  MOTOR_LIFE_TESTING
-    
-  // Init temporary variables
-  ucVentilationCycleCopy=INSPIRATION_CYCLE;
-  uiPproxMax=0;
-  uiVtiTemp=0;
-  uiTiMesTemp=0;
-  ucCounterLPAlarm=0;
-  fAlarmPmax=FALSE;        
-  fAlarmVtiMax=FALSE;
-  ucCounterAlarmVteMin=0;
-}
-
-
-/*******************************************************************************
-* Function Name  : ReadStopVentilationAlarmNumber
-* Description    : Read the alarm number which stops the ventilation
-* Input          : None
-* Output         : None
-* Return         : alarm number
-*******************************************************************************/
-u8  ReadStopVentilationAlarmNumber(void)
-{
-  u16 uiMask;
-  u8  i;
-  u8  ucAlarmNumber=SIZE_BLOWER_ALARM;
-  
-  // Check Alarm which stops ventilation
-  if (uiFlagsAlarm[ALARM_FLAGS1]!=0 ||
-      uiFlagsAlarm[ALARM_FLAGS2]!=0)
-      /*uiFlagsAlarm[ALARM_FLAGS3]!=0 ||
-      uiFlagsAlarm[ALARM_FLAGS4]!=0)*/
-  {
-    for (i=0; i<SIZE_BLOWER_ALARM; i++)
-    {
-      if (stBlowerAlarmStatus[i].bForceVentilToStop==TRUE)
-      {
-        uiMask=stBlowerAlarmStatus[i].uiAlarmMask;
-        if ((uiFlagsAlarm[stBlowerAlarmStatus[i].ucAlarmFlag]&uiMask)==uiMask)
-        {
-          ucAlarmNumber=i;                    
-          break;
-        }
-      }
-    }
-  }    
-  return(ucAlarmNumber);      
-}
-
-
-/*******************************************************************************
-* Function Name  : UpdateAlarmsMeasureID
-* Description    : Update the alarms ventilation measure variables
-* Input          : None
-* Output         : None
-* Return         : alarm number
-*******************************************************************************/
-#ifdef  USE_OPTIMACOMM
-void  UpdateAlarmsMeasureID(void)
-{
-  uiVentilationMeasures[ALARM_ID1_MES]=uiFlagsAlarm[ALARM_FLAGS1];
-  uiVentilationMeasures[ALARM_ID2_MES]=uiFlagsAlarm[ALARM_FLAGS2];  
-}
-#endif  // #ifdef  USE_OPTIMACOMM
-#endif  // #ifndef C_M3_DEVICETEST_TARGET
-
-
-/*******************************************************************************
-* Function Name  : ComputeMotorTemperature
-* Description    : Return temperature (in degres C)
-* Input          : uiADCMotorTemp : ADC value
-* Output         : None
-* Return         : None
-*******************************************************************************/
-u16 ComputeMotorTemperature(u16 uiADCMotorTemp)
-{
-  u16   uiTemp, uiTempDec;
-  u32   ulTemp;
-    
-  for (uiTemp=0; uiTemp<121; uiTemp++)
-  {
-    if (uiADCMotorTemp>=uiADCMotorTempTable[uiTemp])
-      break;    
-  }
-  
-  if (uiADCMotorTemp<uiADCMotorTempTable[120])
-    return(1200);  
-  else if (uiADCMotorTemp>=uiADCMotorTempTable[0])
-    return(0);  
-  else if (uiADCMotorTemp==uiADCMotorTempTable[uiTemp])
-    ulTemp=uiTemp*10;  
-  else   
-  {
-    uiTempDec=((uiADCMotorTempTable[uiTemp-1]-uiADCMotorTemp)*10)/(uiADCMotorTempTable[uiTemp-1]-uiADCMotorTempTable[uiTemp]);  
-    ulTemp=((uiTemp-1)*10)+uiTempDec;
-  }
-  
-  ulTemp*=1000;
-  ulTemp/=uiTechnicalDataSet[GAIN_BLOWER_TEMP_TEC];
-  return((u16)ulTemp);  
-}
-
-
-/*******************************************************************************
-* Function Name  : ComputeFlowInLitersPerMin
-* Description    : Compute the flow in l/min
-* Input          : uFlowRAW : flow digital value, bPositiveFlow= TRUE if positive flow
-* Output         : None
-* Return         : signed Flow in l/min
-*******************************************************************************/
-int16_t ComputeFlowInLitersPerMin(u16 uiFlowRAW, bool bPositiveFlow)
-{
-  u16       uiIndex;
-  int16_t   iFlow;
-  u32       a;
-  int32_t   b;
-  int32_t   y;
-  
-  for (uiIndex=0; uiIndex<stLUTFlowSensor.uiLUT_TableSize; uiIndex++)
-  {
-    if (uiFlowRAW==stLUTFlowSensor.uiFlowSensorTicks[uiIndex])
-    {
-      iFlow=(int16_t)stLUTFlowSensor.uiFlowValue[uiIndex];
-      break;
-    }
-    else if (uiFlowRAW<stLUTFlowSensor.uiFlowSensorTicks[uiIndex])
-    {
-      if (uiIndex==0)
-      {
-        iFlow=(int16_t)(((u32)uiFlowRAW*stLUTFlowSensor.uiFlowValue[uiIndex])/stLUTFlowSensor.uiFlowSensorTicks[uiIndex]);
-      }
-      else
-      {
-        a=(100UL*(stLUTFlowSensor.uiFlowValue[uiIndex]-stLUTFlowSensor.uiFlowValue[uiIndex-1]))/(stLUTFlowSensor.uiFlowSensorTicks[uiIndex]-stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1]);
-        b=((int32_t)stLUTFlowSensor.uiFlowValue[uiIndex-1]*100)-((int32_t)stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1]*a);
-        y=((int32_t)a*(int32_t)uiFlowRAW)+b;
-        iFlow=(int16_t)(y/100);
-      }
-      break;
-    }
-    else
-    {
-      iFlow=(int16_t)stLUTFlowSensor.uiFlowValue[uiIndex];
-    }
-  }
-      
-  if (bPositiveFlow==FALSE)
-    iFlow*=(-1);
-  
-  return(iFlow);
-}
-
-/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Monitoring.txt	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,1375 @@
+/*********************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#define EXTERN extern
+#include "SS.h"                   
+#include "main.h"                   
+#include "_ss_pwm.h"      
+#include "_SS_I2CX_Drivers.h"
+#include "_SS_I2CX_SDP600.h"
+#include "_SS_I2CX_X201641.h"
+#include "Ventilation.h"   
+#include "MotorTempTable.h"
+#include "_SS_FlowComputer.h"
+#include "_SS_TSI_4040.h"
+#include "_SS_Data_Logging.h"
+#include "_SS_OnOffActioner.h"
+#undef EXTERN
+
+#define INIT_VARIABLES
+#define EXTERN
+#include "Monitoring.h"           
+#undef  EXTERN
+#undef  INIT_VARIABLES
+  
+  
+// *********************** Register locations **********************************
+#define DMA_IFCR1    (*(volatile uint32_t *)0x40020004)
+#define DMA_CCR1     (*(volatile uint32_t *)0x40020008)
+#define DMA_CNTDR1   (*(volatile uint32_t *)0x4002000c)
+#define DMA_CPAR1    (*(volatile uint32_t *)0x40020010)
+#define DMA_CMAR1    (*(volatile uint32_t *)0x40020014)
+
+#define ADC1_SR      (*(volatile uint32_t *)0x40012400)
+#define ADC1_SQR1    (*(volatile uint32_t *)0x4001242C)
+#define ADC1_SQR2    (*(volatile uint32_t *)0x40012430)
+#define ADC1_SQR3    (*(volatile uint32_t *)0x40012434)
+#define ADC1_LTR     (*(volatile uint32_t *)0x40012428)
+#define ADC1_HTR     (*(volatile uint32_t *)0x40012424)
+#define ADC1_CR1     (*(volatile uint32_t *)0x40012404)
+#define ADC1_CR2     (*(volatile uint32_t *)0x40012408)
+
+
+// ************************* ADC CONFIGURATION CHANNELS ************************
+#define FREE_MEAS_CHANNEL             0
+#define PPROX_MEAS_CHANNEL            1
+#define CURRENT_MEAS_CHANNEL          2
+#define ALIM_24V_MEAS_CHANNEL         6
+#define TEMP_PHASE_A                  5
+#define TEMP_PHASE_B                  4
+#define TEMP_PHASE_C                  3
+
+// ********************* 24V ALARM MANAGEMENT **********************************
+#ifndef C_M3_DEVICETEST_TARGET
+
+#endif    
+
+
+
+// ************************ I2C SENSORS MANAGEMENT *****************************
+#ifndef C_M3_DEVICETEST_TARGET
+  #define       READING_NO_SENSOR               0
+  #define       READING_FLOW_SENSORS            1
+  //#define       READING_PRESSURE_SENSORS        2
+  #define       STOP_READING_FLOW_SENSORS       3
+  #define       START_READING_FLOW_SENSORS      4
+  #define       NUMBER_I2C_REBOOT               3
+  
+  #define       FLOW_SENSOR_READING             0
+  #define       FLOW_SENSOR_OK                  1
+  #define       FLOW_SENSOR_FAIL                2
+  static          u8            ucStatusSDP600=FLOW_SENSOR_READING;
+  static          u8            ucStatusX201641=FLOW_SENSOR_READING;
+  
+  static volatile u8            ucReadingFlowSensor=START_READING_FLOW_SENSORS;    // I2Cx sensor managment
+  static          u8            ucCounterFlowErrorMeasurement=0;
+  static          u16           uiTotalCounterFlowErrorMeasurement=0;
+
+  #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)  
+    #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
+      #define       SMOOTH_BLOWER_RAW_FLOW_COUNTER      50
+      static          u16           uiBlowerRAWFlowTemp[SMOOTH_BLOWER_RAW_FLOW_COUNTER];                  
+      static          u8            ucIndexBlowerRAWFlowSmooth=0;
+      
+      #define       BLOWER_RAW_FLOW_SAMPLES_NUMBER  200
+      static          u32           ulSumBlowerFlowRAWMes=0;
+      static          u16           uiBlowerRAWFlowSamplesCounter=BLOWER_RAW_FLOW_SAMPLES_NUMBER;
+    #endif
+    
+    #define       SMOOTH_BLOWER_FLOW_LARGE_COUNTER      75//100     // MUST BE HIGHER THAN SMOOTH_BLOWER_FLOW_SMALL_COUNTER
+    #define       SMOOTH_BLOWER_FLOW_SMALL_COUNTER      15      // MUST BE LOWER  THAN SMOOTH_BLOWER_FLOW_LARGE_COUNTER
+    static            int16_t       iTempBlowerFlowForSmallSmooth[SMOOTH_BLOWER_FLOW_SMALL_COUNTER];          
+    static            int16_t       iTempBlowerFlowForLargeSmooth[SMOOTH_BLOWER_FLOW_LARGE_COUNTER];          
+    static            u8            ucIndexSmallBlowerFlowSmooth=0;
+    static            u8            ucIndexLargeBlowerFlowSmooth=0;
+    
+    static            int16_t       idConductancedtSmooth[SMOOTH_BLOWER_FLOW_SMALL_COUNTER]; 
+  #endif  // (SDP600_USED_I2C1_BUS) || (X201641_USED_I2C1_BUS)  
+#endif    // C_M3_DEVICETEST_TARGET
+    
+    
+    
+// ****************** PROXIMAL PRESSURE SENSOR MANAGEMENT **********************
+#ifndef C_M3_DEVICETEST_TARGET
+  #define         SMOOTH_PPROX_PRESSURE_COUNTER   40
+  static  u8              ucIndexPproxPressureSmooth=0;  
+  static  u16             uiProximalPressureTemp[SMOOTH_PPROX_PRESSURE_COUNTER];
+#endif  // C_M3_DEVICETEST_TARGET
+  
+  
+  
+// ********************* MEASURES MANAGEMENT **********************************
+#ifndef C_M3_DEVICETEST_TARGET              
+  // ---- Current measurement
+  static  u32             ulSumCurrentADCMesFiltered=0;
+  static  u32             ulCounterADC_FilteredBlowerCurrentMes=0;
+  
+  // ---- Temperature measurement
+  static  u32             ulADCSumBlowerTemperature=0;
+  static  u16             uiTemperatureSamplesCounter=0;
+  
+  #ifdef TEMPERATURE_TRENDS
+    #ifdef  USE_FLOW_COMPUTER 
+      #define   FLOW_COMPUTER_CYCLE_DETECTION_TIMER                   10        // 100ms
+      static  u8              ucFlowComputerCycle=EXPIRATION_CYCLE;
+      static  u16             uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
+    #else
+      #define   TIME_OUT_TEMPERATURE_MEASUREMENT                      6000      // 60s
+      static  u16             uiTimeOutTemperatureMeasurement=0;
+    #endif  // #ifdef  USE_FLOW_COMPUTER 
+    static  u32             ulADCSumTemperaturePhaseA=0;
+    static  u16             uiADCTemperaturePhaseA;
+    static  u32             ulADCSumTemperaturePhaseB=0;
+    static  u16             uiADCTemperaturePhaseB;
+    static  u32             ulADCSumTemperaturePhaseC=0;
+    static  u16             uiADCTemperaturePhaseC;  
+  #endif
+    
+  // ---- Blower Speed measurment
+  static  u32             ulSumTachoTicks=0;
+  static  u32             ulCounterAverageMotorSpeed=0;
+    
+  // --- Blower current Bessel filter  
+  /*static  u16             uiCurrentADCMesFilteredPrev2;
+  static  u16             uiCurrentADCMesFilteredPrev1;  
+  static  u16             uiCurrentADCMesPrev2;
+  static  u16             uiCurrentADCMesPrev1;
+  static  u16             uiCurrentADCMesFiltered;*/
+
+  // --- Motor voltage
+  static  u32             ulSumADC_MotorVoltage;
+  static  u32             ulCounterADC_MotorVoltage;  
+  
+  // --- Temporary measurements
+  static  u16             uiPproxMax;
+  static  u16             uiVtiTemp;
+  static  u16             uiVteTemp;
+  static  u16             uiTiMesTemp;
+  static  u16             uiTeMesTemp;
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+  
+  
+#ifndef C_M3_DEVICETEST_TARGET  
+  static  u8              ucVentilationCycleCopy=INSPIRATION_CYCLE;
+  static  int32_t         lSumVti=0;
+  static  int32_t         lSumVte=0;
+  static  u8              ucCounterAlarmVteMin=0;
+  static  u8              ucCounterLPAlarm=0;
+#endif  // C_M3_DEVICETEST_TARGET  
+  
+  
+#define RCC_APB2RSTR (*(volatile uint32_t *)0x4002100c)
+
+  
+// ***************** Functions **********************************************
+int16_t ComputeFlowInLitersPerMin(u16 uFlowRAW, bool bPositiveFlow);
+void    ComputeBlowerPower(void);
+u16     ComputeTemperature(u16 uiADCMotorTemp, u16 *puiTempLUT, u16 uiTemperatureGain);
+
+
+/*******************************************************************************
+* Function Name  : ADC1_init
+* Description    : Init ADC1
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ADC1_init(void)
+{
+  // First perform De_init
+  DMA_CCR1 &= (uint32_t)(~0x1);  // channel 1 disable
+  DMA_CCR1 = 0; // Reset Channelx control register
+  DMA_CNTDR1 = 0; // Reset Channelx remaining bytes register
+  DMA_CPAR1 = 0; // Reset Channelx peripheral address register
+  DMA_CMAR1 = 0; // Reset Channelx memory address register
+  DMA_IFCR1 |= DMA_Channel1_IT_Mask; // Reset interrupt pending bits
+  // end de-init
+
+  // Initialise DMA #1
+  DMA_CPAR1 = (uint32_t)(ADC1_BASE + 0x4c);    // base adress of ADC1 ADC_DR register
+  
+  DMA_CMAR1 = (unsigned long)(&uiADC_Value[0]);
+  DMA_CNTDR1 = NUMBER_ADC_CONVERSION;   // numbers of data to be transfered
+  
+  DMA_CCR1 = (3<<12) + (1<<10) + (1<<8) + (1<<7) + (1<<5) /*+ (1<<1)*/; // very high priority, mem size 16 bits, periph size 16 bits, mem increase,/* circular enabled*/, /*transfer complete IT*/
+  DMA_CCR1 |= 1;  // channel 1 enable  
+  
+  
+  
+  // De-init of the ADC 1
+  RCC_APB2RSTR |= RCC_APB2Periph_ADC1;          // enable
+  RCC_APB2RSTR &= ~RCC_APB2Periph_ADC1;         // disable
+  // end De-init of the ADC 1
+      
+  // Select channels of the regular group
+  #ifdef TEMPERATURE_TRENDS  
+    ADC1_SQR1 = ((NUMBER_ADC_CONVERSION-1)<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;
+    ADC1_SQR2 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + TEMP_PHASE_C;  
+    ADC1_SQR3 = (TEMP_PHASE_B<<25) + (TEMP_PHASE_A<<20) + (FREE_MEAS_CHANNEL<<15) + (CURRENT_MEAS_CHANNEL<<10) + (ALIM_24V_MEAS_CHANNEL<<5) + PPROX_MEAS_CHANNEL;      
+  #else
+    ADC1_SQR1 = ((NUMBER_ADC_CONVERSION-1)<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;
+    ADC1_SQR2 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (FREE_MEAS_CHANNEL<<10) + (FREE_MEAS_CHANNEL<<5) + FREE_MEAS_CHANNEL;  
+    ADC1_SQR3 = (FREE_MEAS_CHANNEL<<25) + (FREE_MEAS_CHANNEL<<20) + (FREE_MEAS_CHANNEL<<15) + (CURRENT_MEAS_CHANNEL<<10) + (ALIM_24V_MEAS_CHANNEL<<5) + PPROX_MEAS_CHANNEL;      
+  #endif
+      
+  // 21 micros ADC conversion time
+  ADC1->SMPR2= (7<<27) + (7<<24) + (7<<21) + (7<<18) + (7<<15) + (7<<12) + (7<<9) + (7<<6) + (7<<3) + 7;      
+  ADC1->SMPR1= (7<<21) + (7<<18) + (7<<15) + (7<<12) + (7<<9) + (7<<6) + (7<<3) + 7;   
+  
+  ADC1_CR1  = (1<<8);                                                           // Scan mode enabled
+  ADC1_CR2  = (1<<8);                                                           // DMA mode enabled
+    
+  ADC1_CR2 |= 1;                                                                // start ADC1 - power-on
+
+  // Delay at least 1uSec for ADC calibration/stabilisation. See ADC documentation
+  // Stabilization time > 1uS for ADC, between power-on and start of conversion
+  // Give it 10uSecs just to be sure.   
+  Delay100NS(100);  
+  
+  // Calibration of ADC1
+  ADC1_CR2 |= (1<<3);                                                           // reset calibration registers
+  ADC1_CR2 |= (1<<2);                                                           // Enable calibration
+  while ((ADC1_CR2 & (1<<2)) == (1<<2));                                        // Wait end of calibration
+  
+  ADC1_CR2 |= 1;                                                                // start ADC1 - start conversions    
+}
+
+
+/*******************************************************************************
+* Function Name  : CheckAlimMotorVoltage
+* Description    : Check the voltage range of the 24V power supply
+* Input          : None
+* Output         : None
+* Return         : OPSTATUS_OK or OPSTATUS_FAIL
+*******************************************************************************/
+opstatus_t CheckAlimMotorVoltage(void)
+{
+  if (uiDCinADCMeas<271 || uiDCinADCMeas>2090)
+    return(OPSTATUS_FAIL);                        // <12V or >24V
+  return(OPSTATUS_OK);
+}
+
+
+/*******************************************************************************
+* Function Name  : Compute24VMeasure
+* Description    : Compute the 24V measure
+* Input          : None
+* Output         : None
+* Return         : OPSTATUS_OK or OPSTATUS_FAIL
+*******************************************************************************/
+#ifndef C_M3_DEVICETEST_TARGET
+void Compute24VMeasure(void)
+{
+  u32 ulTemp;
+  u16 uiADC_BlowerVoltage;
+  
+  if (bMemoStartVentilation==TRUE)
+    uiADC_BlowerVoltage=uiAverageADC_MotorVoltage;
+  else
+    uiADC_BlowerVoltage=uiDCinADCMeas;
+    
+  ulTemp=((u32)uiADC_BlowerVoltage*100)/1452;
+  ulTemp+=100;
+  uiTechnicalDataMes[MOTOR_VOLTAGE_TEC_MES]=(u16)ulTemp;
+  uiMotorVoltageMes=(u16)ulTemp;
+}
+#endif
+
+void GetFirstMotorVoltageReading(void)
+{
+  uiAverageADC_MotorVoltage=uiDCinADCMeas;
+}
+/*******************************************************************************
+* Function Name  : ComputeBlowerPower
+* Description    : Compute the power of the blower
+* Input          : None
+* Output         : None
+* Return         : OPSTATUS_OK or OPSTATUS_FAIL
+*******************************************************************************/
+void ComputeBlowerPower(void)
+{
+  uiTechnicalDataMes[MOTOR_POWER_TEC_MES]=((u32)uiMotorVoltageMes*uiBlowerCurrentMes)/10;
+}
+
+/*******************************************************************************
+* Function Name  : SpeedMeasurement
+* Description    : Return blower speed
+* Input          : Tacho counter
+* Output         : None
+* Return         : Blower speed in RPM
+*******************************************************************************/
+u16 SpeedMeasurement(u16 uiTachoCounter)
+{
+  u16 uiSpeedTemp=65500;
+    
+  if (uiTachoCounter>915)
+    uiSpeedTemp=(u16)(60000000UL/uiTachoCounter);        
+  
+  return(uiSpeedTemp);
+}
+
+
+/*******************************************************************************
+* Function Name  : ReadADCInputs
+* Description    : Read all ADC input (function calls every 1ms)
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/  
+void ReadADCInputs(void)
+{ 
+  //u32       ulTerm1, ulTerm2, ulTerm3, ulTerm4, ulTerm5;
+  
+  // ADC Pprox measurement
+  uiProximalPressureADCMes=uiADC_Value[ADC_PPROX_MES];   
+          
+  // ADC DCin measurement
+  uiDCinADCMeas=uiADC_Value[ADC_DCIN_MES];
+  
+  // ADC Blower current measurement
+  ComputeADCBlowerCurrent(FALSE);      
+  
+  // ADC Free measurement  
+  uiADCBlowerTemperatureMeas=uiADC_Value[ADC_FREE_MES];
+     
+  #ifdef TEMPERATURE_TRENDS
+  uiADCTemperaturePhaseA=uiADC_Value[ADC_TEMP_PHASE_A];
+  uiADCTemperaturePhaseB=uiADC_Value[ADC_TEMP_PHASE_B];
+  uiADCTemperaturePhaseC=uiADC_Value[ADC_TEMP_PHASE_C];
+  #endif
+  
+  // 2nd order Bessel Filter (Fcut-out=36Hz, sample rate=1KHz)
+  /*ulTerm1=(919UL*uiADCBlowerCurrent)>>6;
+  ulTerm2=(919UL*uiCurrentADCMesPrev1)>>5;
+  ulTerm3=(919UL*uiCurrentADCMesPrev2)>>6;
+  ulTerm4=(1427UL*uiCurrentADCMesFilteredPrev1)>>1;
+  ulTerm5=259UL*uiCurrentADCMesFilteredPrev2;
+  
+  uiCurrentADCMesFiltered=(ulTerm1+ulTerm2+ulTerm3+ulTerm4-ulTerm5)>>9;
+  uiCurrentADCMesFilteredPrev2=uiCurrentADCMesFilteredPrev1;
+  uiCurrentADCMesFilteredPrev1=uiCurrentADCMesFiltered;  
+  uiCurrentADCMesPrev2=uiCurrentADCMesPrev1;
+  uiCurrentADCMesPrev1=uiADCBlowerCurrent;*/
+  
+  
+  // 2nd order Bessel Filter (Fcut-out=150Hz, sample rate=1KHz)
+  /*ulTerm1=(1929UL*uiADCBlowerCurrent)>>1;
+  ulTerm2=(1929UL*uiCurrentADCMesPrev1);
+  ulTerm3=(1929UL*uiCurrentADCMesPrev2)>>1;
+  ulTerm4=(1095UL*uiCurrentADCMesFilteredPrev1)>>1;
+  ulTerm5=(2479UL*uiCurrentADCMesFilteredPrev2)>>3;
+  
+  uiCurrentADCMesFiltered=(ulTerm1+ulTerm2+ulTerm3+ulTerm4-ulTerm5)>>12;
+  uiCurrentADCMesFilteredPrev2=uiCurrentADCMesFilteredPrev1;
+  uiCurrentADCMesFilteredPrev1=uiCurrentADCMesFiltered;  
+  uiCurrentADCMesPrev2=uiCurrentADCMesPrev1;
+  uiCurrentADCMesPrev1=uiADCBlowerCurrent;*/
+  
+  // --- Start new conversions
+  ADC1->CR2 |= 1;    
+}
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : ComputeMeasurements
+* Description    : Compute different measures
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/  
+void ComputeMeasurements(void)
+{    
+  // ---------------------- Measure Current (A) ----------------------------
+  uiBlowerCurrentMes=ComputeBlowerCurrentInAmper(uiADCBlowerCurrent);
+      
+  // -------------------- Compute motor voltage (V) ------------------------
+  Compute24VMeasure();
+  ComputeBlowerPower();    
+  
+  // ---------------------- Others measurements ----------------------------
+  if (bMemoStartVentilation==TRUE)
+  {
+    // --- Motor speed (RPM) (every 10ms)
+    uiBlowerSpeedMes=SpeedMeasurement(uiTachoTimeTicks);  
+  }  
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+#ifdef TEMPERATURE_TRENDS  
+/*******************************************************************************
+* Function Name  : ComputeAverageOnMeasurements
+* Description    : Average differents mesures : MUST BE CALLED EVERY 10ms 
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/  
+void ComputeAverageOnMeasurements(void)
+{   
+  #ifdef  USE_FLOW_COMPUTER
+    // ----------- USE THE FLOW COMPUTER TO DETECT CYCLE ----------------
+    u16         uiDummy;
+    opstatus_t  opstatus;
+    
+    // Read new flow from flow computer every 10ms  
+    opstatus=SS_Xgetw(flc, &uiDummy);        
+    if (opstatus==OPSTATUS_OK)
+    {
+      // Update flow/pressure displayed
+      uiBlowerFlow=iFlowFromFlowComputer*10;
+      uiPoutPressureMes=uiPressureFromFlowComputer;
+              
+      // Comm with flow computer OK !!    
+      #ifdef  DATA_LOGGING
+      if (bRecordTemperatureTrendsAllowed==FALSE)
+      {
+        bRecordTemperatureTrendsAllowed=TRUE;
+        uiTrendsSampleTime=RECORD_TRENDS_SAMPLE_TIME;
+      }
+      #endif  // DATA_LOGGING
+      
+      // inspiration/expiration cycle detection
+      if (ucFlowComputerCycle==EXPIRATION_CYCLE)
+      {
+        // Inspiration detection
+        if (iFlowFromFlowComputer>50) // 5l/min
+        {
+          uiFlowComputerCycleModificationTimer--;
+          if (uiFlowComputerCycleModificationTimer==0)
+          {
+            ucFlowComputerCycle=INSPIRATION_CYCLE;
+            
+            // Compute temperature of the previous inspiratory cycle
+            if (uiTemperatureSamplesCounter!=0)
+            {
+              uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);           
+              uiADCAverageTemperaturePhaseA=ulADCSumTemperaturePhaseA/uiTemperatureSamplesCounter;
+              uiADCAverageTemperaturePhaseB=ulADCSumTemperaturePhaseB/uiTemperatureSamplesCounter;
+              uiADCAverageTemperaturePhaseC=ulADCSumTemperaturePhaseC/uiTemperatureSamplesCounter;          
+            }
+            ulADCSumBlowerTemperature=0;
+            ulADCSumTemperaturePhaseA=0;
+            ulADCSumTemperaturePhaseB=0;
+            ulADCSumTemperaturePhaseC=0;
+            uiTemperatureSamplesCounter=0;
+          }
+        }
+        else
+          uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
+      }
+      else 
+      {
+        // Record temperature as long as the flow is positive
+        if (iFlowFromFlowComputer>(-10)) // >-1l/min
+        {
+          ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
+          ulADCSumTemperaturePhaseA+=uiADCTemperaturePhaseA;
+          ulADCSumTemperaturePhaseB+=uiADCTemperaturePhaseB;
+          ulADCSumTemperaturePhaseC+=uiADCTemperaturePhaseC;
+          uiTemperatureSamplesCounter++;
+        }
+        
+        // Expiration detection
+        if (iFlowFromFlowComputer<(-50)) // <-5l/min
+        {
+          uiFlowComputerCycleModificationTimer--;
+          if (uiFlowComputerCycleModificationTimer==0)
+            ucFlowComputerCycle=EXPIRATION_CYCLE;
+        }
+        else
+          uiFlowComputerCycleModificationTimer=FLOW_COMPUTER_CYCLE_DETECTION_TIMER;
+      }
+    }
+    else if (opstatus==OPSTATUS_FAIL)
+    {
+      // Comm Failure with flow computer => no data recorded
+      uiBlowerFlow=0;
+      uiPoutPressureMes=0;
+      
+      #ifdef  DATA_LOGGING
+      bRecordTemperatureTrendsAllowed=FALSE;
+      #endif     
+      uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=0;
+    }       
+  #else
+    // ----------- USE THE 24V MEASURE TO DETECT CYCLE ----------------        
+    if (uiDCinADCMeas>500)
+    {
+      // Inspiration
+      ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
+      ulADCSumTemperaturePhaseA+=uiADCTemperaturePhaseA;
+      ulADCSumTemperaturePhaseB+=uiADCTemperaturePhaseB;
+      ulADCSumTemperaturePhaseC+=uiADCTemperaturePhaseC;
+      uiTemperatureSamplesCounter++;
+      uiTimeOutTemperatureMeasurement=TIME_OUT_TEMPERATURE_MEASUREMENT;
+      #ifdef  DATA_LOGGING
+      bRecordTemperatureTrendsAllowed=TRUE;
+      #endif
+    }
+    else if (uiTimeOutTemperatureMeasurement!=0)
+    {
+      // Expiration
+      uiTimeOutTemperatureMeasurement--;
+      if (uiTemperatureSamplesCounter!=0)
+      {
+        uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);           
+        uiADCAverageTemperaturePhaseA=ulADCSumTemperaturePhaseA/uiTemperatureSamplesCounter;
+        uiADCAverageTemperaturePhaseB=ulADCSumTemperaturePhaseB/uiTemperatureSamplesCounter;
+        uiADCAverageTemperaturePhaseC=ulADCSumTemperaturePhaseC/uiTemperatureSamplesCounter;          
+      }
+      ulADCSumBlowerTemperature=0;
+      ulADCSumTemperaturePhaseA=0;
+      ulADCSumTemperaturePhaseB=0;
+      ulADCSumTemperaturePhaseC=0;
+      uiTemperatureSamplesCounter=0;           
+    }  
+    else
+    {
+      uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=0;
+      
+      ulADCSumBlowerTemperature=0;
+      ulADCSumTemperaturePhaseA=0;
+      ulADCSumTemperaturePhaseB=0;
+      ulADCSumTemperaturePhaseC=0;
+      uiTemperatureSamplesCounter=0;   
+      
+      #ifdef  DATA_LOGGING
+      bRecordTemperatureTrendsAllowed=FALSE;
+      #endif            
+    }
+  #endif  // #ifdef  USE_FLOW_COMPUTER      
+}
+#endif  // #ifdef TEMPERATURE_TRENDS     
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+/*******************************************************************************
+* Function Name  : ComputeADCBlowerCurrent
+* Description    : Compute the average current during a PWM cycle (20micros)
+* Input          : bRecordCurrentOffset
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ComputeADCBlowerCurrent(bool bRecordCurrentOffset) 
+{                       
+  if (bRecordCurrentOffset==TRUE)
+  {        
+    uiADCOffsetBlowerCurrent=uiADCBlowerCurrent=uiADC_Value[ADC_CURRENT_MES];    
+  }
+  else
+  {    
+    uiADCBlowerCurrent=uiADC_Value[ADC_CURRENT_MES];              
+  }
+}
+
+
+/*******************************************************************************
+* Function Name  : ComputeBlowerCurrentInAmper
+* Description    : Return blower current value in cAmper (ex: 100=1.00A)
+* Input          : ADC value
+* Output         : None
+* Return         : Blower current in cAmper (ex: 100=1.00A)
+*******************************************************************************/
+int16_t ComputeBlowerCurrentInAmper(u16 uiADCBlowerCurrentLocal)
+{
+  int32_t lTempValue;  
+  
+  // Computation using MOT_CUR_MEAS2
+  lTempValue=(int32_t)uiADCBlowerCurrentLocal-(int32_t)uiADCOffsetBlowerCurrent;
+  lTempValue*=1000;
+  lTempValue/=uiTechnicalDataSet[GAIN_BLOWER_CURRENT_TEC];
+  return(lTempValue);  
+}
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : LaunchFlowReadingOnI2CBus
+* Description    : Open and Read the flow sensor(s) on the I2C bus
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void LaunchFlowReadingOnI2CBus(void)
+{
+  opstatus_t  byOpStatus;
+  u16         uiSensorErr;
+  
+  if (fOpenI2C1SDP600Sensors==FALSE  || fOpenI2C2SDP600Sensors==FALSE   ||
+      fOpenI2C1X201641Sensors==FALSE || fOpenI2C2X201641Sensors==FALSE)
+  {        
+    byOpStatus=SS_Xopen(I2C_SDP600);
+    if (byOpStatus==OPSTATUS_FAIL)
+      uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;     
+    
+    byOpStatus=SS_Xopen(I2C_X201641);
+    if (byOpStatus==OPSTATUS_FAIL)    
+      uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;     
+            
+    ucReadingFlowSensor=STOP_READING_FLOW_SENSORS;
+  }
+  else if (ucReadingFlowSensor==STOP_READING_FLOW_SENSORS)
+  {
+    ucReadingFlowSensor=START_READING_FLOW_SENSORS;
+  }
+  else if (ucReadingFlowSensor==READING_FLOW_SENSORS)
+  {            
+    // Reading SDP600 Flow sensors
+    if (ucStatusSDP600==FLOW_SENSOR_READING)
+    {
+      byOpStatus=SS_Xgetw(I2C_SDP600, &uiSensorErr);    
+      if (byOpStatus==OPSTATUS_OK)                  
+        ucStatusSDP600=FLOW_SENSOR_OK;          
+      else if (byOpStatus==OPSTATUS_FAIL)
+        ucStatusSDP600=FLOW_SENSOR_FAIL;
+    }
+    
+    // Reading X201641 Flow sensors
+    if (ucStatusX201641==FLOW_SENSOR_READING)
+    {
+      byOpStatus=SS_Xgetw(I2C_X201641, &uiSensorErr);    
+      if (byOpStatus==OPSTATUS_OK)            
+        ucStatusX201641=FLOW_SENSOR_OK;          
+      else if (byOpStatus==OPSTATUS_FAIL)          
+        ucStatusX201641=FLOW_SENSOR_FAIL;          
+    }
+    
+    // End of flow measurement?
+    if (ucStatusSDP600!=FLOW_SENSOR_READING && ucStatusX201641!=FLOW_SENSOR_READING)
+    {                              
+      if (ucStatusSDP600==FLOW_SENSOR_OK && ucStatusX201641==FLOW_SENSOR_OK)
+      {      
+        ucCounterFlowErrorMeasurement=0; 
+        #ifdef TIME_MEASUREMENT
+        GPIOB->BRR = GPIO_Pin_5;
+        #endif
+      }
+      else
+      {
+        // Error counters
+        uiTotalCounterFlowErrorMeasurement++;
+        ucCounterFlowErrorMeasurement++;
+        if (ucCounterFlowErrorMeasurement>=NUMBER_I2C_REBOOT)      
+        {
+          //ulErrorCounter|=uiSensorErr;                                                      
+          uiFlagsAlarm[ALARM_FLAGS2]|=FLOW_SENSOR_FAILURE_ALARM_MASK;
+        }
+      }
+      
+      // Next Sensors to measure
+      ucReadingFlowSensor=READING_NO_SENSOR;
+      ucStatusSDP600=FLOW_SENSOR_READING;
+      ucStatusX201641=FLOW_SENSOR_READING;
+    }
+  }
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : ComputeFlowMeasurement
+* Description    : Conpute inspiratory and erxpiratory flow measurements
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ComputeFlowMeasurement(void)
+{
+  #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)
+  int32_t     lValue;
+  u16         uiValue;
+  #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
+    u32         ulValue;
+  #endif
+  #endif
+  
+  if (ucReadingFlowSensor==START_READING_FLOW_SENSORS)
+  {
+    ucReadingFlowSensor=READING_FLOW_SENSORS;
+  }
+  else if (ucReadingFlowSensor==READING_NO_SENSOR)
+  {    
+    ucReadingFlowSensor=READING_FLOW_SENSORS;  
+  
+    // **** Reading of the Inspiratory RAW Flow
+    #if defined(SDP600_USED_I2C1_BUS) || defined(X201641_USED_I2C1_BUS)          
+      #ifdef SDP600_USED_I2C1_BUS          
+        SDP600_ReadADCFlowValue(I2C1, SDP600_BLOWER_FLOW_SENSOR, &uiValue);  
+      #endif
+      #ifdef X201641_USED_I2C1_BUS          
+        X201641_ReadADCFlowValue(I2C1, X201641_BLOWER_FLOW_SENSOR, &uiValue);  
+      #endif
+      if (uiValue==uiTechnicalDataSet[FLOWI_OFFSET_TEC])
+      {
+        uiBlowerFlowRAWMes=0;
+        iBlowerFlowMes=0;
+      }
+      else if (uiValue>uiTechnicalDataSet[FLOWI_OFFSET_TEC])
+      {
+        uiBlowerFlowRAWMes=uiValue-uiTechnicalDataSet[FLOWI_OFFSET_TEC];
+        iBlowerFlowMes=ComputeFlowInLitersPerMin(uiBlowerFlowRAWMes, FALSE);
+      }
+      else
+      {
+        uiBlowerFlowRAWMes=uiTechnicalDataSet[FLOWI_OFFSET_TEC]-uiValue;
+        iBlowerFlowMes=ComputeFlowInLitersPerMin(uiBlowerFlowRAWMes, TRUE);
+      }
+        
+      // Smoothing RWA data signals
+      #ifdef  DISPLAY_AVERAGE_BLOWER_RAW_FLOW
+      uiBlowerRAWFlowTemp[ucIndexBlowerRAWFlowSmooth]=uiBlowerFlowRAWMes;
+      ulValue=0;
+      for (uiValue=0; uiValue<SMOOTH_BLOWER_RAW_FLOW_COUNTER; uiValue++)          
+          ulValue+=uiBlowerRAWFlowTemp[uiValue];  
+      uiBlowerFlowRAWSmoothingMes=ulValue/SMOOTH_BLOWER_RAW_FLOW_COUNTER;                          
+      ucIndexBlowerRAWFlowSmooth++;
+      if (ucIndexBlowerRAWFlowSmooth>=SMOOTH_BLOWER_RAW_FLOW_COUNTER)
+        ucIndexBlowerRAWFlowSmooth=0;
+         
+      // Average of the RAW data signal      
+      ulSumBlowerFlowRAWMes+=uiBlowerFlowRAWSmoothingMes;
+      uiBlowerRAWFlowSamplesCounter--;
+      if (uiBlowerRAWFlowSamplesCounter==0)
+        {           
+        uiAverageBlowerFlowRAWMes=ulSumBlowerFlowRAWMes/BLOWER_RAW_FLOW_SAMPLES_NUMBER;
+        ulSumBlowerFlowRAWMes=0;
+        uiBlowerRAWFlowSamplesCounter=BLOWER_RAW_FLOW_SAMPLES_NUMBER;
+        }
+      #endif  // DISPLAY_AVERAGE_BLOWER_RAW_FLOW
+    
+    
+    // **** Reading of the Inspiratory Flow in l/min
+    /*#ifdef SDP600_USED_I2C1_BUS
+      SDP600_CalculFlowValue(I2C1, SDP600_BLOWER_FLOW_SENSOR, &iBlowerFlowMes);                          
+    #endif
+    #ifdef X201641_USED_I2C1_BUS  
+      X201641_CalculFlowValue(I2C1, X201641_BLOWER_FLOW_SENSOR, &iBlowerFlowMes);                          
+    #endif*/
+    iTempBlowerFlowForSmallSmooth[ucIndexSmallBlowerFlowSmooth]=iBlowerFlowMes;        
+    iTempBlowerFlowForLargeSmooth[ucIndexLargeBlowerFlowSmooth]=iBlowerFlowMes;        
+           
+    // Small Smoothing of the inspiratory flow signal
+    lValue=0;
+    for (uiValue=0; uiValue<SMOOTH_BLOWER_FLOW_SMALL_COUNTER; uiValue++)          
+        lValue+=iTempBlowerFlowForSmallSmooth[uiValue];          
+    iBlowerFlowSmoothingMes=lValue/(int16_t)SMOOTH_BLOWER_FLOW_SMALL_COUNTER;        
+    ucIndexSmallBlowerFlowSmooth++;
+    if (ucIndexSmallBlowerFlowSmooth>=SMOOTH_BLOWER_FLOW_SMALL_COUNTER)
+      ucIndexSmallBlowerFlowSmooth=0;
+    
+    // Large Smoothing of the inspiratory flow signal
+    lValue=0;
+    for (uiValue=0; uiValue<SMOOTH_BLOWER_FLOW_LARGE_COUNTER; uiValue++)          
+        lValue+=iTempBlowerFlowForLargeSmooth[uiValue];          
+    iBlowerFlowSmoothingMesForTrigger=lValue/(int16_t)SMOOTH_BLOWER_FLOW_LARGE_COUNTER;            
+    ucIndexLargeBlowerFlowSmooth++;
+    if (ucIndexLargeBlowerFlowSmooth>=SMOOTH_BLOWER_FLOW_LARGE_COUNTER)
+      ucIndexLargeBlowerFlowSmooth=0; 
+    
+    // Flow for Optima Comm 
+    uiBlowerFlow=iBlowerFlowMes;
+    uiBlowerFlowSmoothingMes=iBlowerFlowSmoothingMes;
+    uiBlowerFlowTriggerMes=iBlowerFlowSmoothingMesForTrigger;
+    #endif  // (SDP600_USED_I2C1_BUS) || (X201641_USED_I2C1_BUS)
+  }
+  
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+double powApprox(double a, double x)
+{
+    union
+    {
+        double d;
+        int A[2];
+    } Z = { a };
+    Z.A[1] = (int)(x * (Z.A[1] - 1072632447) + 1072632447);
+    Z.A[0] = 0;
+    return Z.d;
+}
+/*******************************************************************************
+* Function Name  : ComputeConductance
+* Description    : Compute Conductance
+* Input          : Pressure, Flow
+* Output         : Conductance
+* Return         : None
+*******************************************************************************/
+float prevConductance = 0.0f;
+u8 bufferIndex = 0;
+bool filled = FALSE;
+int16_t littleSum = 0;
+
+void ComputeConductance(void)
+{
+  float pressure = iProximalPressureMes/10.0f;
+  float flow = iBlowerFlowSmoothingMes/100.0f/60.0f;
+  float density = 1.225f;
+  float viscosity = 0.00018f;
+  float calcConductance = 0.0f;
+  
+  if(pressure != 0)
+  {
+          calcConductance  = (100000)*((powApprox((flow*0.001f),1.75)*powApprox(density,0.75)*powApprox(viscosity,0.25)/(pressure / 10.0f)* 98.0638f));
+          calcConductance  = calcConductance * 1000.0f;          
+          if(calcConductance < 60000 && calcConductance > -60000)
+          {
+                  uiConductanceCalc = (int16_t)calcConductance;
+          }         
+  }
+//  int16_t tempValue = idConductancedtSmooth[bufferIndex];
+//  idConductancedtSmooth[bufferIndex]= (int16_t)(calcConductance - prevConductance);//1000;
+//  littleSum += idConductancedtSmooth[bufferIndex];
+//  bufferIndex++;
+//  if(bufferIndex > SMOOTH_BLOWER_FLOW_LARGE_COUNTER)
+//  {
+//    bufferIndex = 0;
+//    if(!filled)
+//    {
+//      filled = TRUE;
+//    }
+//  }
+//  
+//  if(filled)
+//  {
+//    littleSum -= tempValue;    
+//    uidConductanceCalcdt = littleSum/SMOOTH_BLOWER_FLOW_LARGE_COUNTER;
+//  }
+  uidConductanceCalcdt = (int16_t)(calcConductance - prevConductance);
+  prevConductance  = calcConductance;
+}
+/*******************************************************************************
+* Function Name  : ComputeProximalPressureMeasurements
+* Description    : Compute Proximal pressure measurements
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ComputeProximalPressureMeasurements(void)
+{
+  u32 ulValue;
+  u16 uiValue;
+    
+  iProximalPressureMes=((100L*((int16_t)uiProximalPressureADCMes-(int16_t)uiTechnicalDataSet[PPROX_OFFSET_TEC]))/(int16_t)uiTechnicalDataSet[PPROX_GAIN_TEC]);                  
+  if (iProximalPressureMes>0)
+    uiProximalPressureMes=(u16)iProximalPressureMes;
+  else
+    uiProximalPressureMes=0; 
+  uiNegativeProximalPressureMes=iProximalPressureMes;
+  
+  // Smoothing proximal pressure
+  uiProximalPressureTemp[ucIndexPproxPressureSmooth]=uiProximalPressureMes;  
+  ulValue=0;
+  for (uiValue=0; uiValue<SMOOTH_PPROX_PRESSURE_COUNTER; uiValue++)          
+      ulValue+=uiProximalPressureTemp[uiValue];          
+  uiProximalPressureSmoothingMes=ulValue/SMOOTH_PPROX_PRESSURE_COUNTER;
+  
+  ucIndexPproxPressureSmooth++;
+  if (ucIndexPproxPressureSmooth>=SMOOTH_PPROX_PRESSURE_COUNTER)
+    ucIndexPproxPressureSmooth=0;                             
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : ComputeOffsetProximalPressureSensor
+* Description    : Compute offset of the proximal pressure sensor
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ComputeOffsetProximalPressureSensor(void)
+{
+  u32 ulOffsetSum=0;
+  u16 i;
+  
+  for (i=0; i<64; i++)
+  {
+    ulOffsetSum+=uiADC_Value[ADC_PPROX_MES];
+    uiTempoSysTick=5;
+    while (uiTempoSysTick!=0){}
+  }
+  uiTechnicalDataSet[PPROX_OFFSET_TEC]=ulOffsetSum>>6;    
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : VentilationMonitoringAndAlarms
+* Description    : Compute measurements and alarms during ventilation
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void VentilationMonitoringAndAlarms(void)
+{
+  u16 uiTotalTimeMes;
+  
+  if (bMemoStartVentilation==TRUE && uiTechnicalDataSet[DEVICE_MODE_TEC]==VENTILATION_MODE)
+  {    
+    if (ucVentilationCycle==INSPIRATION_CYCLE)
+    {
+      // ***************** INSPIRATION ******************
+      if (ucVentilationCycleCopy==EXPIRATION_CYCLE)
+      {
+        // --- Beginning of inspiration
+        ucVentilationCycleCopy=INSPIRATION_CYCLE;
+        SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_ON);
+        
+        // Update Vte measurement
+        uiVentilationMeasures[VTE_MES]=uiVteTemp;
+        
+        // Update Te measurement
+        uiVentilationMeasures[TE_MES]=uiTeMesTemp;
+       
+        // Update Average ADC Motor Voltage
+        if (ulCounterADC_MotorVoltage!=0)
+          uiAverageADC_MotorVoltage=ulSumADC_MotorVoltage/ulCounterADC_MotorVoltage;
+        
+        // Update Current measurement
+        if (ulCounterADC_FilteredBlowerCurrentMes!=0)
+          uiBreathBlowerCurrentMes=ComputeBlowerCurrentInAmper(ulSumCurrentADCMesFiltered/ulCounterADC_FilteredBlowerCurrentMes);
+        ulSumCurrentADCMesFiltered=0; ulCounterADC_FilteredBlowerCurrentMes=0;
+        
+        // Update average blower speed
+        if (ulCounterAverageMotorSpeed!=0)
+          uiAverageBlowerSpeedMes=SpeedMeasurement(ulSumTachoTicks/ulCounterAverageMotorSpeed);
+        ulSumTachoTicks=0;    
+        ulCounterAverageMotorSpeed=0;
+
+        // Update average motor temperature during inspiration        
+        if (uiTemperatureSamplesCounter!=0)
+        {          
+            uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(ulADCSumBlowerTemperature/uiTemperatureSamplesCounter);          
+            if (uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]>890)
+              uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_TEMPERATURE_ALARM_MASK;
+            else if (uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]<810)
+              uiFlagsAlarm[ALARM_FLAGS2]&=(~MOTOR_TEMPERATURE_ALARM_MASK);
+        }
+        ulADCSumBlowerTemperature=0; uiTemperatureSamplesCounter=0;
+                        
+        // --- Pmax=0
+        uiPproxMax=0;
+                        
+        // --- Vti=0
+        lSumVti=0;
+        uiRecordVtiMes=uiVentilationMeasures[VTI_MES];        
+        
+        // --- Dislay Breath rate
+        uiTotalTimeMes=uiVentilationMeasures[TI_MES]+uiVentilationMeasures[TE_MES];
+        if (uiTotalTimeMes>0)
+          uiVentilationMeasures[BREATH_RATE_MES]=600000/uiTotalTimeMes;
+        
+        // --- Ti=0
+        uiTiMesTemp=0;
+        
+        // --- Max flow
+        iBlowerFlowSmoothingMaxMes=0;
+                        
+        // --- Alarm Vte Min
+        if (uiVentilationMeasures[VTE_MES]<uiVentilationSet[VTE_MIN_ALARM_SET] && enVentilationMode!=CPAP_MODE)
+        {
+          ucCounterAlarmVteMin++;
+          if (ucCounterAlarmVteMin>=5)
+          {
+            ucCounterAlarmVteMin=5;
+            uiFlagsAlarm[ALARM_FLAGS1]|=LOW_VTE_ALARM_MASK;
+          }
+        }
+        else
+        {
+          ucCounterAlarmVteMin=0;
+          uiFlagsAlarm[ALARM_FLAGS1]&=(~LOW_VTE_ALARM_MASK);
+        }
+      }
+      else //if (ucVentilationCycle==EXPIRATION_CYCLE)
+      {
+        // --- During inspiration
+        
+        // --- Motor Speed
+        ulSumTachoTicks+=uiTachoTimeTicks;    
+        ulCounterAverageMotorSpeed++;
+        
+        // --- Blower Current
+        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
+        ulCounterADC_FilteredBlowerCurrentMes++;
+        
+        // --- Inc Pmax
+        if (uiProximalPressureMes>uiPproxMax)
+          uiPproxMax=uiProximalPressureMes;
+        
+        // --- Inc max flow
+        if (iBlowerFlowSmoothingMes>iBlowerFlowSmoothingMaxMes)
+          iBlowerFlowSmoothingMaxMes=iBlowerFlowSmoothingMes;
+        
+        // --- Inc Vti
+        if (iBlowerFlowMes>30)
+          lSumVti+=iBlowerFlowMes;
+        uiVtiTemp=(u32)lSumVti/6000;       
+        
+        // --- Inc Ti
+        uiTiMesTemp++;
+
+        // --- Motor temperature        
+        ulADCSumBlowerTemperature+=uiADCBlowerTemperatureMeas; 
+        uiTemperatureSamplesCounter++;
+        
+        // --- Alarm Pmax
+        if (uiProximalPressureMes>uiVentilationSet[HIGH_PRESSURE_ALARM_SET] && enVentilationMode!=CPAP_MODE)
+        {
+          uiFlagsAlarm[ALARM_FLAGS1]|=HIGH_PRESSURE_ALARM_MASK;
+          fAlarmPmax=TRUE;          
+        }
+                                
+        // --- Alarm Vti Max
+        if ((uiVtiTemp>uiVentilationSet[VTI_MAX_ALARM_SET] && enVentilationMode==PS_MODE)   ||
+            (uiVtiTemp>uiVentilationSet[VTI_MAX_ALARM_SET] && enVentilationMode==APCV_MODE))
+        {
+          uiFlagsAlarm[ALARM_FLAGS1]|=HIGH_VTI_ALARM_MASK;
+          fAlarmVtiMax=TRUE;
+        }
+      }
+    }
+    else
+    {
+      // ***************** EXPIRATION ******************
+      if (ucVentilationCycleCopy==INSPIRATION_CYCLE)
+      {
+        // --- Beginning of Expiration
+        ucVentilationCycleCopy=EXPIRATION_CYCLE;
+        SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_OFF);
+        
+        // Update Pprox max measurement
+        uiVentilationMeasures[PPROX_MAX_MES]=uiPproxMax;
+          
+        // Update Vti measurement
+        uiVentilationMeasures[VTI_MES]=uiVtiTemp;
+        
+        // Update Ti measurement
+        uiVentilationMeasures[TI_MES]=uiTiMesTemp;
+        
+        // --- Motor Speed
+        ulSumTachoTicks+=uiTachoTimeTicks;    
+        ulCounterAverageMotorSpeed++;
+        
+        // --- Blower Current
+        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
+        ulCounterADC_FilteredBlowerCurrentMes++;
+        
+        // --- Vte=0
+        lSumVte=0;
+        
+        // --- Te=0
+        uiTeMesTemp=0;      
+        
+        // --- Alarm Low Pressure
+        if ((uiVentilationMeasures[PPROX_MAX_MES]<(uiVentilationSet[PS_SET]-5) && enVentilationMode==PS_MODE)   ||
+            (uiVentilationMeasures[PPROX_MAX_MES]<(uiVentilationSet[PI_SET]-5) && enVentilationMode==APCV_MODE) ||
+            (uiVentilationMeasures[PPROX_MAX_MES]<uiVentilationSet[LOW_PRESSURE_ALARM_SET] && enVentilationMode==AVC_MODE))
+        { 
+          ucCounterLPAlarm++;
+          if (ucCounterLPAlarm>=4)
+          {
+            ucCounterLPAlarm=4;
+            uiFlagsAlarm[ALARM_FLAGS1]|=LOW_PRESSURE_ALARM_MASK;
+          }
+        }
+        else
+        {
+          ucCounterLPAlarm=0;
+          uiFlagsAlarm[ALARM_FLAGS1]&=(~LOW_PRESSURE_ALARM_MASK);
+        }
+        
+        // --- Clear Alarm High pressure        
+        if (fAlarmPmax==FALSE)
+          uiFlagsAlarm[ALARM_FLAGS1]&=(~HIGH_PRESSURE_ALARM_MASK);
+        fAlarmPmax=FALSE;
+        
+        // --- Clear Alarm Vti Max
+        if (fAlarmVtiMax==FALSE)
+          uiFlagsAlarm[ALARM_FLAGS1]&=(~HIGH_VTI_ALARM_MASK);
+        fAlarmVtiMax=FALSE;
+      }
+      else
+      {
+        // --- During Expiration
+        
+        // --- Motor Speed
+        ulSumTachoTicks+=uiTachoTimeTicks;    
+        ulCounterAverageMotorSpeed++;
+        
+        // --- Blower Current
+        ulSumCurrentADCMesFiltered+=uiADCBlowerCurrent;
+        ulCounterADC_FilteredBlowerCurrentMes++;
+        
+        // --- Inc Vte
+        if (iBlowerFlowMes<(-30))
+          lSumVte+=iBlowerFlowMes;
+        if (lSumVte<0)
+          uiVteTemp=(u32)(lSumVte/(-6000));
+        else
+          uiVteTemp=0;
+        
+        // --- Inc Te
+        uiTeMesTemp++;
+        if (uiTeMesTemp>60000) uiTeMesTemp=60000;
+        
+        // --- Average motor voltage
+        if (uiTeMesTemp==100)
+        {
+          ulSumADC_MotorVoltage=0;
+          ulCounterADC_MotorVoltage=0;
+        }
+        else if (uiTeMesTemp>100)
+        {
+          ulSumADC_MotorVoltage+=uiDCinADCMeas;
+          ulCounterADC_MotorVoltage++;
+        }
+      }
+    }
+  } 
+  else // if (bMemoStartVentilation==TRUE && uiTechnicalDataSet[DEVICE_MODE_TEC]==VENTILATION_MODE) 
+  {
+    #ifndef TEMPERATURE_TRENDS
+    uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES]=ComputeMotorTemperature(uiADCBlowerTemperatureMeas);
+    #endif
+  }
+}
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+#ifndef C_M3_DEVICETEST_TARGET
+/*******************************************************************************
+* Function Name  : ClearVentilationAlarm
+* Description    : Clear all ventilation Alarms
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ClearAllVentilationAlarms(void)
+{
+  u8    i;
+  u8    ucAlarmFlag;
+  
+  for (i=0; i<SIZE_BLOWER_ALARM; i++)
+  {    
+    ucAlarmFlag=stBlowerAlarmStatus[i].ucAlarmFlag;
+    if (stBlowerAlarmStatus[i].bVentilationAlarm==TRUE && (ucAlarmFlag==ALARM_FLAGS1 || ucAlarmFlag==ALARM_FLAGS2))
+      uiFlagsAlarm[ucAlarmFlag]&=(~stBlowerAlarmStatus[i].uiAlarmMask);
+  }
+}
+
+                   
+/*******************************************************************************
+* Function Name  : ClearAlarm
+* Description    : Clear a specific alarm
+* Input          : Mask of the alarm
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ClearAlarm(u8 ucAlarmFlag, u16 uiMask)
+{ 
+  uiFlagsAlarm[ucAlarmFlag]&=(~uiMask);
+}
+
+                   
+/*******************************************************************************
+* Function Name  : ClearAllMeasures
+* Description    : Clear all ventilation measures
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ClearAllMeasures(void)
+{
+  u8  i;
+  
+  // Reset measures except alarms
+  for (i=0; i<SIZE_LRM_GROUP; i++)
+  {
+    if (i!=ALARM_ID1_MES && i!=ALARM_ID2_MES)// && i!=ALARM_ID3_MES && i!=ALARM_ID4_MES)      
+      uiVentilationMeasures[i]=0;
+  }  
+  
+  // Reset others measures
+  uiBlowerSpeedMes=0;             uiAverageBlowerSpeedMes=0;      // Speed=0 RPM
+  ulSumTachoTicks=0;              ulCounterAverageMotorSpeed=0;
+  uiBreathBlowerCurrentMes=0;                                   // Blower current=0 A
+  ulSumCurrentADCMesFiltered=0;   ulCounterADC_FilteredBlowerCurrentMes=0;
+  bDisplayInspiratoryTrigger=FALSE;    
+  #ifdef  MOTOR_LIFE_TESTING
+    uiAverateMotorTempMes=0;
+  #endif  // #ifdef  MOTOR_LIFE_TESTING
+    
+  // Init temporary variables
+  ucVentilationCycleCopy=INSPIRATION_CYCLE;
+  uiPproxMax=0;
+  uiVtiTemp=0;
+  uiTiMesTemp=0;
+  ucCounterLPAlarm=0;
+  fAlarmPmax=FALSE;        
+  fAlarmVtiMax=FALSE;
+  ucCounterAlarmVteMin=0;
+}
+
+
+/*******************************************************************************
+* Function Name  : ReadStopVentilationAlarmNumber
+* Description    : Read the alarm number which stops the ventilation
+* Input          : None
+* Output         : None
+* Return         : alarm number
+*******************************************************************************/
+u8  ReadStopVentilationAlarmNumber(void)
+{
+  u16 uiMask;
+  u8  i;
+  u8  ucAlarmNumber=SIZE_BLOWER_ALARM;
+  
+  // Check Alarm which stops ventilation
+  if (uiFlagsAlarm[ALARM_FLAGS1]!=0 ||
+      uiFlagsAlarm[ALARM_FLAGS2]!=0)
+      /*uiFlagsAlarm[ALARM_FLAGS3]!=0 ||
+      uiFlagsAlarm[ALARM_FLAGS4]!=0)*/
+  {
+    for (i=0; i<SIZE_BLOWER_ALARM; i++)
+    {
+      if (stBlowerAlarmStatus[i].bForceVentilToStop==TRUE)
+      {
+        uiMask=stBlowerAlarmStatus[i].uiAlarmMask;
+        if ((uiFlagsAlarm[stBlowerAlarmStatus[i].ucAlarmFlag]&uiMask)==uiMask)
+        {
+          ucAlarmNumber=i;                    
+          break;
+        }
+      }
+    }
+  }    
+  return(ucAlarmNumber);      
+}
+
+
+/*******************************************************************************
+* Function Name  : UpdateAlarmsMeasureID
+* Description    : Update the alarms ventilation measure variables
+* Input          : None
+* Output         : None
+* Return         : alarm number
+*******************************************************************************/
+#ifdef  USE_OPTIMACOMM
+void  UpdateAlarmsMeasureID(void)
+{
+  uiVentilationMeasures[ALARM_ID1_MES]=uiFlagsAlarm[ALARM_FLAGS1];
+  uiVentilationMeasures[ALARM_ID2_MES]=uiFlagsAlarm[ALARM_FLAGS2];  
+}
+#endif  // #ifdef  USE_OPTIMACOMM
+#endif  // #ifndef C_M3_DEVICETEST_TARGET
+
+
+/*******************************************************************************
+* Function Name  : ComputeMotorTemperature
+* Description    : Return temperature (in degres C)
+* Input          : uiADCMotorTemp : ADC value
+* Output         : None
+* Return         : None
+*******************************************************************************/
+u16 ComputeMotorTemperature(u16 uiADCMotorTemp)
+{
+  u16   uiTemp, uiTempDec;
+  u32   ulTemp;
+    
+  for (uiTemp=0; uiTemp<121; uiTemp++)
+  {
+    if (uiADCMotorTemp>=uiADCMotorTempTable[uiTemp])
+      break;    
+  }
+  
+  if (uiADCMotorTemp<uiADCMotorTempTable[120])
+    return(1200);  
+  else if (uiADCMotorTemp>=uiADCMotorTempTable[0])
+    return(0);  
+  else if (uiADCMotorTemp==uiADCMotorTempTable[uiTemp])
+    ulTemp=uiTemp*10;  
+  else   
+  {
+    uiTempDec=((uiADCMotorTempTable[uiTemp-1]-uiADCMotorTemp)*10)/(uiADCMotorTempTable[uiTemp-1]-uiADCMotorTempTable[uiTemp]);  
+    ulTemp=((uiTemp-1)*10)+uiTempDec;
+  }
+  
+  ulTemp*=1000;
+  ulTemp/=uiTechnicalDataSet[GAIN_BLOWER_TEMP_TEC];
+  return((u16)ulTemp);  
+}
+
+
+/*******************************************************************************
+* Function Name  : ComputeFlowInLitersPerMin
+* Description    : Compute the flow in l/min
+* Input          : uFlowRAW : flow digital value, bPositiveFlow= TRUE if positive flow
+* Output         : None
+* Return         : signed Flow in l/min
+*******************************************************************************/
+int16_t ComputeFlowInLitersPerMin(u16 uiFlowRAW, bool bPositiveFlow)
+{
+  u16       uiIndex;
+  int16_t   iFlow;
+  u32       a;
+  int32_t   b;
+  int32_t   y;
+  
+  for (uiIndex=0; uiIndex<stLUTFlowSensor.uiLUT_TableSize; uiIndex++)
+  {
+    if (uiFlowRAW==stLUTFlowSensor.uiFlowSensorTicks[uiIndex])
+    {
+      iFlow=(int16_t)stLUTFlowSensor.uiFlowValue[uiIndex];
+      break;
+    }
+    else if (uiFlowRAW<stLUTFlowSensor.uiFlowSensorTicks[uiIndex])
+    {
+      if (uiIndex==0)
+      {
+        iFlow=(int16_t)(((u32)uiFlowRAW*stLUTFlowSensor.uiFlowValue[uiIndex])/stLUTFlowSensor.uiFlowSensorTicks[uiIndex]);
+      }
+      else
+      {
+        a=(100UL*(stLUTFlowSensor.uiFlowValue[uiIndex]-stLUTFlowSensor.uiFlowValue[uiIndex-1]))/(stLUTFlowSensor.uiFlowSensorTicks[uiIndex]-stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1]);
+        b=((int32_t)stLUTFlowSensor.uiFlowValue[uiIndex-1]*100)-((int32_t)stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1]*a);
+        y=((int32_t)a*(int32_t)uiFlowRAW)+b;
+        iFlow=(int16_t)(y/100);
+      }
+      break;
+    }
+    else
+    {
+      iFlow=(int16_t)stLUTFlowSensor.uiFlowValue[uiIndex];
+    }
+  }
+      
+  if (bPositiveFlow==FALSE)
+    iFlow*=(-1);
+  
+  return(iFlow);
+}
+
+/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
+
+
+
--- a/Safety.c	Tue Jun 09 22:57:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-
-/* Includes ------------------------------------------------------------------*/
-#define EXTERN extern
-#include "SS.h"                   
-#include "_SS_OnOffActioner.h"
-#include "main.h"
-#undef EXTERN
-
-#define INIT_VARIABLES
-#define EXTERN
-#include "safety.h"           
-#undef  EXTERN
-#undef  INIT_VARIABLES
-
-
-
-/*******************************************************************************
-* Function Name  : ControlHW
-* Description    : Control the STOP_BLOWER and WDI_CPLD pins
-* Input          : BLOWER_OFF__PAT_CPLD or BLOWER_ON__PAT_CPLD or BLOWER_OFF__STOP_PAT_CPLD 
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ControlHW(_enHWStatus enHWStatus)
-{
-  // Clock=0
-  SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);
-  
-  /*if (enHWStatus==BLOWER_OFF__PAT_CPLD)
-  {          
-    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_OFF);    // CTL_ACTUATORS=0          
-    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=0
-    
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);    // Clock=0
-    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_ON);          // CTL_CPLD=1      
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=1
-  }*/
-  if (enHWStatus==BLOWER_ON__PAT_CPLD)
-  {          
-    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_ON);     // CTL_ACTUATORS=1
-    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=1, WDI_CPLD=0
-    
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);    // Clock=0
-    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_ON);          // CTL_CPLD=1      
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=1, WDI_CPLD=1
-  }
-  else //if (enHWStatus==BLOWER_OFF__STOP_PAT_CPLD)
-  {          
-    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_OFF);    // CTL_ACTUATORS=0
-    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
-    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=0    
-  }      
-}
-
-
-
-/*******************************************************************************
-* Function Name  : TestStopBlowerInputPin
-* Description    : Test the state of the STOP_BLOWER input pin
-* Input          : None
-* Output         : None
-* Return         : OPSTATUS_OK if the pin="0"
-*******************************************************************************/
-opstatus_t TestStopBlowerInputPin(void)
-{
-  if (GPIO_ReadInputDataBit(sPortConfig[STOP_BLOWER_PORT].Port, sPortConfig[STOP_BLOWER_PORT].Pin)==Bit_RESET)    
-    return(OPSTATUS_OK);
-  return(OPSTATUS_FAIL);  
-}
-/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Safety.txt	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,75 @@
+
+/* Includes ------------------------------------------------------------------*/
+#define EXTERN extern
+#include "SS.h"                   
+#include "_SS_OnOffActioner.h"
+#include "main.h"
+#undef EXTERN
+
+#define INIT_VARIABLES
+#define EXTERN
+#include "safety.h"           
+#undef  EXTERN
+#undef  INIT_VARIABLES
+
+
+
+/*******************************************************************************
+* Function Name  : ControlHW
+* Description    : Control the STOP_BLOWER and WDI_CPLD pins
+* Input          : BLOWER_OFF__PAT_CPLD or BLOWER_ON__PAT_CPLD or BLOWER_OFF__STOP_PAT_CPLD 
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ControlHW(_enHWStatus enHWStatus)
+{
+  // Clock=0
+  SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);
+  
+  /*if (enHWStatus==BLOWER_OFF__PAT_CPLD)
+  {          
+    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_OFF);    // CTL_ACTUATORS=0          
+    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=0
+    
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);    // Clock=0
+    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_ON);          // CTL_CPLD=1      
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=1
+  }*/
+  if (enHWStatus==BLOWER_ON__PAT_CPLD)
+  {          
+    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_ON);     // CTL_ACTUATORS=1
+    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=1, WDI_CPLD=0
+    
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_OFF);    // Clock=0
+    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_ON);          // CTL_CPLD=1      
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=1, WDI_CPLD=1
+  }
+  else //if (enHWStatus==BLOWER_OFF__STOP_PAT_CPLD)
+  {          
+    SS_Xputdw(act, CTL_ACTUATORS|FLAG_ACTIONER_OFF);    // CTL_ACTUATORS=0
+    SS_Xputdw(act, CTL_CPLD|FLAG_ACTIONER_OFF);         // CTL_CPLD=0      
+    SS_Xputdw(act, CLK_ACTUATORS|FLAG_ACTIONER_ON);     // Clock=1    => STOP_BLOWER=0, WDI_CPLD=0    
+  }      
+}
+
+
+
+/*******************************************************************************
+* Function Name  : TestStopBlowerInputPin
+* Description    : Test the state of the STOP_BLOWER input pin
+* Input          : None
+* Output         : None
+* Return         : OPSTATUS_OK if the pin="0"
+*******************************************************************************/
+opstatus_t TestStopBlowerInputPin(void)
+{
+  if (GPIO_ReadInputDataBit(sPortConfig[STOP_BLOWER_PORT].Port, sPortConfig[STOP_BLOWER_PORT].Pin)==Bit_RESET)    
+    return(OPSTATUS_OK);
+  return(OPSTATUS_FAIL);  
+}
+/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Screens.cpp	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,143 @@
+#include "TS_DISCO_F429ZI.h"
+#include "LCD_DISCO_F429ZI.h" 
+#include "Screens.h"
+#include "main.h"
+
+bool refreshScreen = true;
+// Pos 1 2 (row of button )
+void DrawBigButton(LCD_DISCO_F429ZI lcd, uint8_t position, char* array)
+{
+   BSP_LCD_SetFont(&Font20);  
+   uint8_t text_array[30];
+   sprintf((char*)text_array, array);  
+   switch (position)
+   {
+       case 1:
+       lcd.DrawRect(BigButtonX, BigButton1Y, BigButtonWidth , BigButtonHeight );
+       lcd.DisplayStringAt(0, LINE(4), (uint8_t *)&text_array, CENTER_MODE);
+       break;
+       case 2:
+       lcd.DrawRect(BigButtonX, BigButton2Y, BigButtonWidth , BigButtonHeight );
+       lcd.DisplayStringAt(0, LINE(7), (uint8_t *)&text_array, CENTER_MODE);
+       break;
+       case 3:
+       lcd.DrawRect(BigButtonX,BigButton3Y,BigButtonWidth ,BigButtonHeight );
+       lcd.DisplayStringAt(0, LINE(10), (uint8_t *)&text_array, CENTER_MODE);
+       break;
+       case 4:
+       lcd.DrawRect(BigButtonX,BigButton4Y,BigButtonWidth ,BigButtonHeight );
+       lcd.DisplayStringAt(0, LINE(13), (uint8_t *)&text_array, CENTER_MODE);
+       default:
+       break;
+   }
+}
+
+void CreatStartupScreen(LCD_DISCO_F429ZI lcd)
+{
+    lcd.Clear(LCD_COLOR_DARKGRAY);
+    uint8_t text_array[30];
+    // Show Title Line - Select Mode 
+     BSP_LCD_SetFont(&Font20);          
+     sprintf((char*)text_array, "Select Mode");
+     lcd.ClearStringLine(1);   
+     lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&text_array, CENTER_MODE);
+    // Show Two Buttons 
+    // first CPAP Mode 
+    DrawBigButton(lcd, 1, "CPAP");
+        // On Press SHOW CPAP Screen 
+    // second NIV 
+    DrawBigButton(lcd, 2, "NIV");
+        // On Press show NIV Screen    
+}
+void CreateCPAPMainScreen(LCD_DISCO_F429ZI lcd)
+{
+    lcd.Clear(LCD_COLOR_DARKGRAY);
+    uint8_t text_array[30];
+    // Show Title Line - Select Mode 
+     BSP_LCD_SetFont(&Font20);          
+     sprintf((char*)text_array, "CPAP");   
+     lcd.ClearStringLine(1);
+     lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&text_array, CENTER_MODE);
+    // Show Two Buttons 
+    // first CPAP Mode 
+    DrawBigButton(lcd, 1, "START");
+        // On Press SHOW CPAP Screen 
+    // second NIV 
+    DrawBigButton(lcd, 2, "SETTINGS");
+        // On Press show NIV Screen   
+    DrawBigButton(lcd, 3, "BACK"); 
+}
+void CreateCPAPMainSettingsScreen(LCD_DISCO_F429ZI lcd)
+{
+   lcd.Clear(LCD_COLOR_DARKGRAY); 
+    uint8_t text_array[30];
+    // Show Title Line - Select Mode 
+     BSP_LCD_SetFont(&Font20);          
+     sprintf((char*)text_array, "CPAP Settings");   
+     lcd.ClearStringLine(1);
+     lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&text_array, CENTER_MODE);
+    // Show Two Buttons 
+    // first CPAP Mode 
+    DrawBigButton(lcd, 1, "PEEP"); 
+    DrawBigButton(lcd, 2, "TI"); 
+    DrawBigButton(lcd, 3, "OTHER ->"); 
+    DrawBigButton(lcd, 4, "BACK"); 
+}
+
+
+void CreateNIVMainScreen(LCD_DISCO_F429ZI lcd)
+{
+    lcd.Clear(LCD_COLOR_DARKGRAY);
+    uint8_t text_array[30];
+    // Show Title Line - Select Mode 
+     BSP_LCD_SetFont(&Font20);          
+     sprintf((char*)text_array, "NIV");   
+     lcd.ClearStringLine(1);
+     lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&text_array, CENTER_MODE);
+    // Show Two Buttons 
+    // first CPAP Mode 
+    DrawBigButton(lcd, 1, "START");
+        // On Press SHOW CPAP Screen 
+    // second NIV 
+    DrawBigButton(lcd, 2, "SETTINGS");
+        // On Press show NIV Screen  
+    DrawBigButton(lcd, 3, "BACK");  
+}
+void showScreen(ScreenState screen,LCD_DISCO_F429ZI lcd)
+{ 
+    if ( refreshScreen == false )
+        return;
+    switch(screen) 
+    {
+        case StartUp :
+                CreatStartupScreen(lcd); 
+                refreshScreen = false;               
+        break;
+        case  CPAPMain :
+                CreateCPAPMainScreen(lcd);
+                refreshScreen = false;
+        break;
+        case  NIVMain :
+                CreateNIVMainScreen(lcd);
+                refreshScreen = false;
+        break;
+        case  CPAPRunning:
+        break;
+        case   CPAPSettingsMain:
+            CreateCPAPMainSettingsScreen(lcd);
+            refreshScreen = false;
+        break;
+        case  CPAPSettingsDetailView:
+        break;
+        case NIVRunning:
+        break;
+        case  NIVSettingsMain:
+        break;
+        case  NIVSettingsDetailView:
+        break;
+
+
+
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Screens.h	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,39 @@
+#ifndef __SCREENS_H
+#define __SCREENS_H
+#ifdef TARGET_DISCO_F429ZI
+#include "TS_DISCO_F429ZI.h"
+#include "LCD_DISCO_F429ZI.h"
+
+#define BigButtonX          40
+#define BigButtonWidth      160
+#define BigButtonHeight     35
+
+#define BigButton1Y        70
+#define BigButton2Y        130
+#define BigButton3Y        190
+#define BigButton4Y        250
+
+typedef enum 
+{
+ StartUp = 0,
+ CPAPMain = 1,
+ NIVMain = 2,
+ CPAPRunning = 3,
+ CPAPSettingsMain = 4,
+ CPAPSettingsDetailView = 5,
+ NIVRunning = 6,
+ NIVSettingsMain = 7,
+ NIVSettingsDetailView = 8   
+} ScreenState;
+
+extern bool refreshScreen;
+
+void CreatStartupScreen(LCD_DISCO_F429ZI lcd);
+void DrawBigButton(LCD_DISCO_F429ZI lcd, uint8_t position, char* array);
+void showScreen(ScreenState screen,LCD_DISCO_F429ZI lcd);
+
+#else
+#error "This class must be used with DISCO_F429ZI board only."
+#endif // TARGET_DISCO_F429ZI
+
+#endif   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Touch.cpp	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,176 @@
+#include "Touch.h"
+#include "main.h"
+#include "Screens.h"
+
+// in Bigbutton position same as draw big button position 
+// out 1 touch detected 0 no touch detected
+
+uint16_t x, y = 0;
+uint16_t touch_x, touch_y = 0;
+bool press_detected = false;
+
+TS_StateTypeDef TS_State;
+TS_StateTypeDef Old_TS_State;
+
+void CheckTs()
+{
+    ts.GetState(&TS_State);      
+    if (TS_State.TouchDetected)
+    {
+        x = TS_State.X;
+        y = TS_State.Y;
+    } 
+    if ((Old_TS_State.TouchDetected) && (!TS_State.TouchDetected))
+    {
+     touch_x = x;
+     touch_y = y;
+     press_detected = true;   
+    }   
+    Old_TS_State = TS_State;
+}
+
+
+bool CheckBigButtonTouch (uint8_t position)
+{
+    bool result = false;
+    if((touch_x >= BigButtonX) && (touch_x<=(BigButtonX + BigButtonWidth)))
+    {
+        switch(position)
+        {
+            case 1: 
+                if((touch_y >= BigButton1Y)&&(touch_y <= (BigButton1Y+BigButtonHeight)))
+                {
+                    result = true;
+                    press_detected = false;  
+                } 
+            break;
+            case 2:
+                if((touch_y >= BigButton1Y)&&(touch_y <= (BigButton2Y+BigButtonHeight)))
+                { 
+                    result = true; 
+                    press_detected = false; 
+                } 
+            break;
+            case 3:
+                if((touch_y >= BigButton3Y)&&(touch_y <= (BigButton3Y+BigButtonHeight)))
+                { 
+                    result = true;
+                    press_detected = false;  
+                }
+            break; 
+            case 4:
+                if((touch_y >= BigButton4Y)&&(touch_y <= (BigButton4Y+BigButtonHeight)))
+                { 
+                    result = true;
+                    press_detected = false;  
+                }
+            break; 
+                 
+        }       
+    }
+
+    return result; 
+}
+
+void CheckPress(ScreenState screen)
+{
+    if(press_detected)
+    {
+        switch(screen)
+        {
+            case StartUp:
+                //Mode Cpap
+                if(CheckBigButtonTouch(1))
+                {
+                    display_screen = CPAPMain;
+                    refreshScreen = true;
+                    break; 
+                }
+                // Mode niv 
+                if(CheckBigButtonTouch (2))
+                {
+                    display_screen = NIVMain;
+                    refreshScreen = true;
+                    break; 
+                }               
+            break;
+            case  CPAPMain :
+                            //Mode Cpap
+                if(CheckBigButtonTouch(1))
+                {
+                    display_screen = CPAPRunning; // Start CPAP
+                    refreshScreen = true;
+                    break; 
+                }
+                // Mode niv 
+                if(CheckBigButtonTouch (2)) // Settings CPAP
+                {
+                    display_screen = CPAPSettingsMain;
+                    refreshScreen = true;
+                    break; 
+                }
+                if(CheckBigButtonTouch (3)) 
+                {
+                    display_screen = StartUp;     // Back to main screen 
+                    refreshScreen = true;
+                    break; 
+                }                                  
+            break;
+            case NIVMain :
+                if(CheckBigButtonTouch(1))
+                {
+                    display_screen = NIVRunning; // Start NIV
+                    refreshScreen = true;
+                    break; 
+                }
+                // Mode niv 
+                if(CheckBigButtonTouch (2)) // Settings NIV
+                {
+                    display_screen =  NIVSettingsMain;
+                    refreshScreen = true;
+                    break; 
+                }
+                if(CheckBigButtonTouch (3)) // Back
+                {
+                    display_screen = StartUp;     // Back to main screen 
+                    refreshScreen = true;
+                    break; 
+                } 
+            break;
+            case CPAPRunning:
+            break;
+            case  CPAPSettingsMain:
+                if(CheckBigButtonTouch(1))
+                {
+                    //display_screen = NIVRunning; // Start NIV
+                    refreshScreen = true;
+                    break; 
+                }
+                // Mode niv 
+                if(CheckBigButtonTouch (2)) // Settings NIV
+                {
+                    //display_screen =  NIVSettingsMain;
+                    refreshScreen = true;
+                    break; 
+                }
+                if(CheckBigButtonTouch (4)) // Back
+                {
+                    display_screen = CPAPMain;     // Back to main screen 
+                    refreshScreen = true;
+                    break; 
+                } 
+            break;       
+            case   CPAPSettingsDetailView:
+            break;
+            case NIVRunning:
+            break;
+            case  NIVSettingsMain:
+            break;
+            case NIVSettingsDetailView:
+            break;
+            default:
+            break;
+        }       
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Touch.h	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,14 @@
+#ifndef __TOUCH_H
+#define __TOUCH_H
+#ifdef TARGET_DISCO_F429ZI
+#include "TS_DISCO_F429ZI.h"
+#include "LCD_DISCO_F429ZI.h"
+#include "Screens.h"
+void CheckTs();
+void CheckPress(ScreenState screen);
+
+#else
+#error "This class must be used with DISCO_F429ZI board only."
+#endif // TARGET_DISCO_F429ZI
+
+#endif   
--- a/Ventilation.c	Tue Jun 09 22:57:20 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3355 +0,0 @@
-
-/* Includes ------------------------------------------------------------------*/
-#define EXTERN extern
-#include <stdlib.h>                   
-#include <string.h>                   
-#include "SS.h"                   
-#include "main.h"
-#include "_SS_OnOffActioner.h"
-#include "_SS_Pwm.h"
-#include "Monitoring.h"
-#include "Safety.h"
-#include "_SS_Data_Logging.h"
-#include "_SS_Record_Settings.h"
-#include "_SS_I2CX_SDP600.h"
-#include "_SS_I2CX_X201641.h"
-#include "_SS_OptimaComm.h"
-#undef EXTERN
-
-#define INIT_VARIABLES
-#define EXTERN 
-#include "Ventilation.h"   
-#undef  EXTERN
-#undef  INIT_VARIABLES
-
-
-/* Internal constants --------------------------------------------------------*/
-// ******************* Min-max PI or PDF ***************************************
-#define       MAX_VOLTAGE_REF                           MAX_PI_OUTPUT  // MAX_PI_OUTPUT = 1343 = 18.5micros = 93.3%, want 80%
-#define       MIN_VOLTAGE_REF                           MIN_PI_OUTPUT
-#define       INTEGRAL_MAX                              (2147483647)
-#define       INTEGRAL_MIN                              (-2147483648)
-
-
-#ifndef C_M3_DEVICETEST_TARGET 
-  /* Internal variables --------------------------------------------------------*/
-  // ******************* MANAGED CONSTANT SPEED ****************************
-  static  u16           uiBlowerSpeedSetting;
-  static  int32_t       lIntegral_Speed_I;
-  static  bool          bMaxPIOutputSpeedI;
-  static  bool          bMinPIOutputSpeedI;
-    
-    
-  // ************* MANAGED BAROMETRIC VENTILATION *************************  
-  static  u16           uiIpapSettingTemp;
-  static  u16           uiTeBaroSet;
-  static  int32_t       lIntegral_Pressure_I;
-  static  bool          bMaxPIOutputPressureI;
-  static  bool          bMinPIOutputPressureI; 
-  static  u16           uiTiD;
-  static  u8            ucIndexTableSlope;
-  #define   TEMPO_TRIGGER_EXPI                30
-  static  u8            ucTempoTriggerExpiAuto;
-  #define   MIN_THRESHOLD_EXPI_TRIGGER_AUTO   25
-  static  u8            ucExpiTriggerTreshold;
-  static  u8            fFirstCycleInspi;
-     
-  // ----------- Main blower management during expiration -------------------  
-  static  u16           uiPWMatTheEndOfInspiration;
-  static  bool          fFirstCycleExpi;      
-  static  u16           uiEpapSettingTemp;
-  static  int32_t       lIntegral_Pressure_E;
-  static  bool          bMaxPIOutputPressureE;
-  static  bool          bMinPIOutputPressureE;     
-  static  u16           uiPWMatTheEndOfExpiration;  
-  static  u16           uiTeD;  
-  static  bool          fBlockCloseLoop;
-  
-  static  u16           uiTiTyp;  
-    
-  // ************* MANAGED VOLUMETRIC VENTILATION *************************  
-  static  u32           ulMaxIFlowSet;
-  static  u32           ulMinIFlowSet;
-  static  u32           ulDecFlowStep;
-  static  u16           uiTeVoluSet;
-  static  u16           uiProximalPressureAtTheEndOfInspiration;
-  static  int32_t       lIntegral_Flow_I;
-  static  bool          bMaxPIOutputFlowI;
-  static  bool          bMinPIOutputFlowI;    
-  static  int16_t       iVtAdjust=0;
-  static  u8            ucCounterHPAlarm=0;    
-    
-    
-  // ******************* MANAGED_CPAP_VENTILATION ******************************  
-  #define EXPIRATORY_DISCONNECTION_TIME_OUT         500   // 500ms
-  #define CPAP_DISCONNECTION_TEST_PERIODICITY       4000  // 4s
-  static  u16           uiDisconnectionTime;  
-  static  u16           uiDisconnectionTimeInCPAP;    
-  static  u16           uiMemoPWMDuringDisconnection;
-  //static  u8            ucStandByMode;
-  
-  // ***************** MANAGED INSPIRATORY TRIGGER *****************************
-  #define MAX_DELTA_FLOW                            100   // 1 l/min
-  #define SIZE_DELTA_INSPIRATORY_FLOW_BUFFER        40
-  #define NUMBER_TRIGGER_VALID                      20
-  #define NUMBER_MIN_FLOW_VALUE                     30
-  //static  int16_t       iBufferIFlowDelta[SIZE_DELTA_INSPIRATORY_FLOW_BUFFER];  
-  static  u8            ucInspiTriggerScheduler;
-  static  u8            ucMinFlowCounter;
-  static  int16_t       iInspiratoryFlowMin;
-  //static  int16_t       iOldInspiratoryFlowSmoothingMesForTrigger;
-  #define SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER      250
-  static  int16_t       iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER];
- // static  int16_t       iBufferConductance[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER];
-  static  u8            ucCounterTriggerValid;
-  static  int16_t       iFlowBaseLineReference;
-  static  bool          bDetectionConstantFlow;  
-
-  
-  // *********************** MANAGED MONITORING FOR MLT ************************
-  static  u16           uiMLT_PressureSetPoint;
-  #ifdef MOTOR_LIFE_TESTING
-    #define MLT_AVERAGE_MONITORING                 1000
-    static  u16           uiAverageMonitoringMLT;    
-    static  u32           ulMLT_SumSpeedMes;
-    static  u32           ulMLT_SumCurrentMes;
-    static  u32           ulMLT_SumTemperatureMes;
-    static  u32           ulMLT_SumBlowerVoltage;
-    static  u16           uiMLT_EnableAlarm;    
-  #endif  // #ifdef MOTOR_LIFE_TESTING
-      
-  
-  // ************************ MANAGED CALIBRATION ******************************
-  typedef enum
-  {
-    INIT_FLOW_CALIB_TEST=0,
-    SET_GAS_TYPE,
-    SET_GAS_STANDARD,
-    START_FLOW_READING,
-    SEND_FLOW_COMMAND,
-    READ_FLOW_VALUE,        
-    SEND_HIGH_FLOW_CALIB_REQUEST,    
-    WAIT_FOR_HIGH_FLOW_CALIB_ACK,
-    PREPARE_FAILURE_COMMAND,
-    PREPARE_SUCCESS_COMMAND,
-    SEND_COMMAND_TO_PF300,
-    CHECK_COMMAND_FROM_PF300,
-    END_OF_CALIBRATION,
-  } type_enLowFlowCalibrationStep;
-
-  typedef enum
-  {
-    INIT_PRESSURE_CALIB_TEST=0,
-    START_PRESSURE_READING,    
-    SEND_PRESSURE_COMMAND,    
-    READ_PRESSURE_VALUE,  
-    PRESSURE_CALIB_FAILURE_COMMAND,
-    PRESSURE_CALIB_SUCCESS_COMMAND,
-    PRESSURE_CALIB_SEND_COMMAND_TO_PF300,
-    PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300,
-    PRESSURE_CALIB_END_OF_CALIBRATION,
-  } type_enPressureCalibrationStep;
-  
-  #define SIZE_BUFFER_FLOW_VALUE                    15
-  typedef struct
-  {
-    unsigned char   ucIndex;
-    bool            bFirstPartOfTheCRReceived;
-    char            szValue[SIZE_BUFFER_FLOW_VALUE];
-  } type_stFlow;
-  
-  // Flow and pressure calibration  
-  #define TIME_OUT_RECEPTION_PACKET_FROM_PF300      2000  // 2s
-  #define SAMPLE_RATE_BETWEEN_TWO_FLOW              5000  // 5s  
-  #define SIZE_RX_BUFFER_PF300                      20  
-  static  u16                                     uiCalibrationTimeOut;
-  static  unsigned char                           ucIndexAnswerFromPF300;
-  static  char                                    szAnswerFromPF300[SIZE_RX_BUFFER_PF300];
-  static  char                                    szExpectedAnswerFromPF300[SIZE_RX_BUFFER_PF300];
-  static  u8                                      ucNumberOfBytesToCheckFromPF300Answer;    
-  
-  // Flow calibration
-  static  type_enLowFlowCalibrationStep           enLowFlowCalibrationStep;
-  static  type_enLowFlowCalibrationStep           enGoBackToStep;
-  static  unsigned long                           ulSumFlowTicks;
-  static  unsigned int                            uiFlowTicksSamplesCounter;
-  //static  type_stLUTFlowSensor                    stTemporayLUTFlowSensor;  
-  static  bool                                    bHighFlowCalibrationInProgress;    
-  static  unsigned int                            uiMotorDutyCyleForFlowCalib;
-  static  unsigned int                            uiImHereMsgTimer;
-  
-  // Pressure calibration
-  #define SAMPLE_RATE_BETWEEN_TWO_PRESSURE          10000  // 30s             
-  static  type_enPressureCalibrationStep          enPressureCalibrationStep;
-  static  type_enPressureCalibrationStep          enPressureCalibGoBackToStep;
-  static  u32                                     ulSumPressureTicks;
-  static  u16                                     uiPressureTicksSamplesCounter;
-  
-  // List of command to PF300
-  static  const char                              szPF300_CmdSwitchOffEcho[]={"%CM#5$0\r"};    // Command Echo from PF300 off
-  static  const char                              szPF300_AnswerSwitchOffEcho[]={"%CM#5"};     // Answer echo off from PF300 (WO \r)
-  static  const char                              szPF300_SetAirGasType[]={"%WS#1$0\r"};       // command Air  
-  static  const char                              szPF300_AnswerAirGasType[]={"%WS#1$0"};      // Answer Air  
-  static  const char                              szPF300_SetGasStandard[]={"%WS#3$1\r"};      // Command STPD
-  static  const char                              szPF300_AnswerGasStandard[]={"%WS#3$1"};     // Answer STPD  
-  static  const char                              szPF300_ReadLowFlowCmd[]={"%RM#1\r"};        // Command read low flow
-  static  const char                              szPF300_ReadLowFlowAnswer[]={"%RM#1$"};      // Answer read low flow
-  static  const char                              szPF300_ReadHighFlowCmd[]={"%RM#0\r"};       // Command read high flow
-  static  const char                              szPF300_ReadHighFlowAnswer[]={"%RM#0$"};     // Answer read high flow 
-  static  const char                              szPF300_ReadPdiffCmd[]={"%RM#3\r"};          // Command read pressure diff.
-  static  const char                              szPF300_ReadPdiffAnswer[]={"%RM#3$"};        // Answewr read pressure diff.
-  
-  // List of Command to Handset
-  static  const char                              szRequestHighFlowCalib[]={"@N"};
-  static  const char                              szEndOfCalibOK[]={"@S"};  
-  static  const char                              szImHere[]={"@*"};
-    
-    
-  // ---------------- Management FRAM for settings -----------------------------
-  #ifdef RECORD_SETTINGS      
-  #endif    // RECORD_SETTINGS           
-  
-  // -------------------- Manage Motor starting --------------------------------
-  #ifndef TEMPERATURE_TRENDS
-  static  u8              ucStartVentilationScheduler=0;  
-  #endif
-  static  enMaroubraModes enPreviousMode;
-  static  u16             uiPreviousDeviceMode;
-#endif      // C_M3_DEVICETEST_TARGET
-  
-    
-#ifndef C_M3_DEVICETEST_TARGET   
-  #define SIZE_SLOPE2_TABLE   21
-  const unsigned char ucSlope2Table[SIZE_SLOPE2_TABLE]= {
-  0,  35, 50, 59, 65, 70, 74, 77, 80, 83,
-  85, 87, 89, 91, 92, 94, 95, 96, 98, 99,
-  100 };
-  
-  // Table pente inspiratoire 2
-  #define SIZE_SLOPE3_TABLE   41
-  const unsigned char ucSlope3Table[SIZE_SLOPE3_TABLE]= {
-  0,  20, 35, 44, 50, 55, 59, 62, 65, 68, 70,
-  72, 74, 76, 77, 79, 80, 81, 83, 84, 85, 86,
-  87, 88, 89, 90, 91, 91, 92, 93, 94, 94, 95,
-  96, 96, 97, 98, 98, 99, 99, 100 };
-  
-  // Table pente inspiratoire 3
-  #define SIZE_SLOPE4_TABLE   61
-  const unsigned char ucSlope4Table[SIZE_SLOPE4_TABLE]= {
-  0,  11, 26, 35, 41, 46, 50, 53, 56, 59, 61,
-  63, 65, 67, 68, 70, 71, 73, 74, 75, 76, 77,
-  78, 79, 80, 81, 82, 83, 83, 84, 85, 86, 86,
-  87, 88, 88, 89 ,90, 90, 91, 91, 92, 92, 93,
-  93, 94, 94, 95, 95, 96, 96, 96, 97, 97, 98,
-  98, 99, 99, 99, 100, 100 };
-  
-  
-  // Maximum allowed flow in expiration Flow=f(PEEP set) (example: flow-by max=29L/min @ 5hPa)
-  const   u16           uiMaximumFlowInExpiration[41]={                    
-    0, 1300, 1830, 2250, 2600, 2900, 3180, 3430, 3670, 3900, 
-    4110, 4310, 4500, 4680, 4860, 5030, 5200, 5360, 5510, 5660,
-    5810, 5950, 6090, 6230, 6360, 6500, 6620, 6750, 6870, 7000,
-    7120, 7230, 7350, 7460, 7580, 7690, 7800, 7900, 8010, 8110, 8220
-  };  
-#endif  // C_M3_DEVICETEST_TARGET
-
-
-/* Internal functions --------------------------------------------------------*/
-#ifndef C_M3_DEVICETEST_TARGET   
-  u16           ComputeTe(u16 uiF, u16 uiTi);
-  void          ComputeInspiratoryFlowSetPointInAVC(u16 uiTypeOfPatient, u16 uiVtc, u16 uiTi, u16 uiFlowShape, u32 *ulMaxFlow, u32 *ulMinFlow, u32 *ulFlowStep);
-  unsigned char TestTriggerExpiratoire(unsigned char ucValeurSeuil, unsigned int uiPressureSetting);
-  bool          TestInspiratoryTrigger(bool bSpont, u16 uiTe, u16 uiFlowThreshold);
-  int16_t       UpdateInspiratoryFlowAverage(void);
-  int16_t       UpdateInspiratoryConductanceAverage(void);
-  void          ResetInspiratoryConductanceAverage(void);
-  bool          TestInspiratorySlowTrigger(int16_t iTheFlowBaseLine, u16 uiFlowTreshold);
-  void          ApplyDefaultValueToTemporaryVentilationSettings(void);  
-  void          ApplyDefaultValueToTechnicalSettings(void);
-  void          ApplyAllDefaultValues(void);
-  bool          ApplyNewVentilationMode(void);
-  void          ApplyDefaultFlowLUT(void);
-  void          CheckFlowLUTRange(void);
-  void          ManageFlowCalibration(void);
-  void          ManagePressureCalibration(void);
-  void          ManageCstPressure(void);
-#endif  // C_M3_DEVICETEST_TARGET
-
-  
-  
-#ifndef C_M3_DEVICETEST_TARGET 
-/*******************************************************************************
-* Function Name  : InitSettings
-* Description    : Initialize parameters for ventilation
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void InitSettings(void)
-{    
-  uiPreviousDeviceMode=0xFF;
-  enPreviousMode=NUMBER_OF_MODE;     
-            
-  // --- Init Settings
-  uiTechnicalDataMes[SW_VERSION_TEC_MES]=MAROUBRA_BLOWER_SW_VERSION;
-  bComputeOffsetSensors=FALSE;
-        
-  #ifdef RECORD_SETTINGS
-    // Read and init FRAM        
-    if (InitSettingsZoneAndTechnicalZoneInFRAM()==OPSTATUS_OK)
-    {      
-      if (ReadSettingsZoneAndTechnicalZoneInFRAM()==OPSTATUS_FAIL)
-      {
-        uiFlagsAlarm[ALARM_FLAGS2]|=FRAM_FAILURE_ALARM_MASK;
-        ApplyAllDefaultValues();
-      }
-    }  
-    else
-    {
-      uiFlagsAlarm[ALARM_FLAGS2]|=FRAM_FAILURE_ALARM_MASK;
-      ApplyAllDefaultValues();
-    }
-  #else  
-    ApplyAllDefaultValues();
-  #endif
-    
-  // Compute offsets sensors if necessary
-  if (bComputeOffsetSensors==TRUE)
-  {    
-    // ------ Update Blower Flow sensor offset before ventilation -------
-    #ifdef SDP600_USED_I2C1_BUS
-    SDP600_ComputeOffsetFlowSensorOnI2C1(SDP600_BLOWER_FLOW_SENSOR);      
-    #endif  // SDP600_USED_I2C1_BUS 
-    
-    #ifdef X201641_USED_I2C1_BUS
-    X201641_ComputeOffsetFlowSensorOnI2C1(X201641_BLOWER_FLOW_SENSOR);
-    #endif  // X201641_USED_I2C1_BUS                
-                
-    // ----- Update Proximal Pressure sensor offset before ventilation -------
-    ComputeOffsetProximalPressureSensor();             
-  }
-        
-  // Check Technical settings range
-  CheckTechnicalSettingsRange();
-  
-  // Check Flow LUT
-  CheckFlowLUTRange();
-  
-  // Check temporary ventilation setting range
-  if (CheckTemporaryVentilationSettingRange()==OPSTATUS_FAIL)
-  {
-    ApplyDefaultValueToTemporaryVentilationSettings();
-    uiFlagsAlarm[ALARM_FLAGS2]|=VENTILATION_SETTINGS_RANGE_ALARM_MASK;
-  }
-
-  // --- Update computed settings (Te,...)
-  UpdateSettings();
-  
-  #ifdef MOTOR_LIFE_TESTING
-    uiTechnicalDataSet[DEVICE_MODE_TEC]=PRESSURE_CST_MODE;
-    uiTechnicalDataSet[START_STOP_VENTILATION]=1;
-  #endif
-}
-
-
-/*******************************************************************************
-* Function Name  : InitVentilation
-* Description    : Initialize variables for ventilation
-*                  Function called :
-*                     - when we start ventilation
-*                     - when we change of ventilation mode
-*                     - when we change of device mode
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void InitVentilation(void)
-{ 
-  ucVentilationCycle=EXPIRATION_CYCLE;
-  uiTiD=0;  
-  uiTeD=0;
-  uiTiTyp = 1000;  
-  bManualBreath=FALSE;
-  
-  if (enPreviousMode==NUMBER_OF_MODE)
-  {
-    // Start ventilation
-    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;  
-    uiDisconnectionTimeInCPAP=CPAP_DISCONNECTION_TEST_PERIODICITY;  
-    uiMemoPWMDuringDisconnection=0;
-    fBlockCloseLoop=FALSE;     
-  }
-  
-  ClearAllVentilationAlarms();
-  ClearAllMeasures();
-  
-  switch(uiTechnicalDataSet[DEVICE_MODE_TEC])
-  {
-  default:
-  case VENTILATION_MODE:
-    {      
-      if (enVentilationMode==APCV_MODE || enVentilationMode==PS_MODE)
-      {
-        if (enPreviousMode==APCV_MODE || enPreviousMode==PS_MODE)
-        {
-          // --- We are already in pressure mode
-        }
-        else
-        {
-          // --- Start a pressure mode
-          fFirstCycleInspi=TRUE;
-          uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF; 
-          
-          if (enPreviousMode!=AVC_MODE)
-          {
-            uiPWMatTheEndOfExpiration=MIN_VOLTAGE_REF;
-            lIntegral_Pressure_E=0;
-            bMaxPIOutputPressureE=FALSE;
-            bMinPIOutputPressureE=FALSE;
-            fFirstCycleExpi=TRUE;   
-          }
-        }                        
-      }
-      else if (enVentilationMode==AVC_MODE)
-      {      
-        iVtAdjust=0;
-        fFirstCycleInspi=TRUE;
-        uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;
-        
-        if (enPreviousMode!=APCV_MODE && enPreviousMode!=PS_MODE)
-        {           
-          uiPWMatTheEndOfExpiration=MIN_VOLTAGE_REF;
-          lIntegral_Pressure_E=0;
-          bMaxPIOutputPressureE=FALSE;
-          bMinPIOutputPressureE=FALSE;
-          fFirstCycleExpi=TRUE;   
-        }
-      }
-      else if (enVentilationMode==CPAP_MODE)
-      {              
-        Ki_Pressure_I=1000;  
-        uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;   
-        lIntegral_Pressure_I=0;
-        bMaxPIOutputPressureI=FALSE;
-        bMinPIOutputPressureI=FALSE;        
-      }
-      break;
-    }  
-  case ONE_CST_PWM_MODE:
-    {       
-      uiInspirationBlowerPWMTec=250;
-      break;
-    }
-  case TWO_CST_PWM_MODE:
-    {      
-      uiInspirationBlowerPWMTec=350; 
-      uiExpirationBlowerPWMTec=150;
-      break;
-    }
-  case CST_SPEED_MODE:
-    {           
-      uiBlowerSpeedSet=15000;
-      uiBlowerSpeedSetting=5000; 
-      break;
-    }
-  case FLOW_CAL_MODE:
-    {      
-      enLowFlowCalibrationStep=INIT_FLOW_CALIB_TEST;
-      bHighFlowCalibrationInProgress=FALSE;
-      stTemporayLUTFlowSensor.uiLUT_TableSize=0;
-      uiCalibrationTimeOut=(TIME_OUT_BLOWER_HANDSET_COMM*20); // 2s
-      break;
-    }
-  case PRESSURE_CAL_MODE:
-    {      
-      enPressureCalibrationStep=INIT_PRESSURE_CALIB_TEST;
-      uiCalibrationTimeOut=(TIME_OUT_BLOWER_HANDSET_COMM*20); // 2s
-      break;
-    }
-  case PRESSURE_CST_MODE:
-    {
-      uiMLT_PressureSetPoint=10;
-      lIntegral_Pressure_I=0;
-      bMaxPIOutputPressureI=FALSE;
-      bMinPIOutputPressureI=FALSE;  
-     
-      #ifdef MOTOR_LIFE_TESTING
-      uiMLT_EnableAlarm=5000;  // 5s before enabling alarm            
-      uiAverageMonitoringMLT=MLT_AVERAGE_MONITORING;    
-      ulMLT_SumSpeedMes=0;
-      ulMLT_SumCurrentMes=0;
-      ulMLT_SumTemperatureMes=0;
-      ulMLT_SumBlowerVoltage=0;
-      #endif  // #ifdef MOTOR_LIFE_TESTING
-      break;
-    }
-  }   
-  enPreviousMode=enVentilationMode; 
-}
-
-
-/*******************************************************************************
-* Function Name  : StopAllActuators
-* Description    : Stop all actuators
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void StopAllActuators(void)
-{ 
-  // Stop main blower
-  SS_Xclose(mdrv);   
-
-  // Valve OFF
-  SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_OFF);      
-}    
-
-/*******************************************************************************
-* Function Name  : CalculateHoseDrop
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-u16 CalculateHoseDrop(void)
-{
-  u16 hoseDrop = (u16)(10*(iBlowerFlowSmoothingMes/100.0f/60.0f * 0.5f));
-  return hoseDrop;
-}
-
-/*******************************************************************************
-* Function Name  : ManageCPAPVentilation
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageCPAPVentilation(void)
-{  
-  
-
-  
-  // *************************** UPDATE SETTINGS *******************************
-  if (ApplyNewVentilationMode()==TRUE)
-    return;
-          
-  // **************************** Cycle detection ******************************
-  // Test Synchronisation
-  /*if (iBlowerFlowSmoothingMesForTrigger<(-500) && ucVentilationCycle==INSPIRATION_CYCLE)  
-    ucVentilationCycle=EXPIRATION_CYCLE; */ 
-  int32_t peakP = 2;//(int32_t)uiVentilationSet[PS_CPAP_SET];
-  // Cycle detection  
-  if (ucVentilationCycle==INSPIRATION_CYCLE)
-  {
-    uiTiD++;
-    if(uiTiD < (0.1f * uiTiTyp))
-    {
-      peakP =(int32_t)( uiVentilationSet[PS_CPAP_SET] * ((uiTiD* 1.0f)/(0.1f * uiTiTyp)));
-    }
-    else if(uiTiD < (1.0f * uiTiTyp))
-    {
-      peakP = ((int32_t)uiVentilationSet[PS_CPAP_SET] - ((int32_t)(uiVentilationSet[PS_CPAP_SET] * (uiTiD * 1.0f)/(1.1f * uiTiTyp)))) + 20;
-    }
-    else
-    {
-      peakP = 2;
-    }
-    
-    if (uiTiD>5000 || (uiTiD>TiBaroSet_P_MIN && TestTriggerExpiratoire(20, uiVentilationSet[PS_CPAP_SET])==TRUE))
-    {
-      ucVentilationCycle=EXPIRATION_CYCLE;
-      uiPWMatTheEndOfInspiration = uiInspirationBlowerPWMTec;
-      if(uiTiD < 2000)
-      {
-        uiTiTyp = uiTiD;
-      }
-      else
-      {
-        uiTiTyp = 2000;
-      }
-      
-      uiTeD=0;      
-    }
-  }
-  else
-  {    
-    uiTeD++;
-    if (uiTeD>TE_SET_MAX) uiTeD=TE_SET_MAX;
-        
-    if (TestInspiratoryTrigger(TRUE, uiTeD, 15)==TRUE)
-    {
-      ucVentilationCycle=INSPIRATION_CYCLE;      
-      uiTiD=0;
-    }    
-  }
-  
-  // Barometric Mode : error computation
-  ControlPressure((int32_t)(peakP + CalculateHoseDrop()));
-}
-
-/*******************************************************************************
-* Function Name  : ControlPressure
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-int32_t previousError = 0;
-int32_t   lIntegralSum = 0;
-void ControlPressure(int32_t setPressure)//pressure in cmH2O*10
-{
-  int32_t   lPropTerm;                  
-  int32_t   lIntegralTerm;
-  int32_t   lDerivativeTerm;
-  int32_t   lOutputPressure;
-  
-  
-  int32_t lError = setPressure - uiProximalPressureMes;
-  
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
-  lIntegralTerm += (int32_t)(uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I] * lError);
-  lDerivativeTerm = (int32_t)(uiTechnicalDataSet[KP_FLOW_I]*(lError - previousError/1000));
-  previousError = lError;
-  
-  // Close loop in pressure
-  if ((lIntegralTerm + lIntegralSum) > INTEGRAL_MAX) 
-    {
-      lIntegralSum = INTEGRAL_MAX;       
-    }
-  else if ((lIntegralTerm - lIntegralSum)< INTEGRAL_MIN)
-    {
-      lIntegralSum = INTEGRAL_MIN;       
-    }
-   else
-    {
-      lIntegralSum += lIntegralTerm;
-    }
-        
-  lOutputPressure = (lDerivativeTerm>>19) + (lIntegralSum>>16) + (lPropTerm>>13) ;
-   
-  lOutputPressure+=uiPWMatTheEndOfInspiration;
-  
-  
-  // Limit and Update blower PWM
-  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-    {
-    bMaxPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-    }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-    {
-    bMinPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-  else
-    {
-    bMaxPIOutputPressureI = FALSE;
-    bMinPIOutputPressureI = FALSE;
-    uiInspirationBlowerPWMTec = lOutputPressure;
-    }
-      
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
-  
-}
-
-
-/*******************************************************************************
-* Function Name  : DavidCControlPressure
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void DavidCControlPressure(int32_t setPressure)//pressure in cmH2O*10
-{
-  int32_t   lPropTerm;                  
-  int32_t   lIntegralTerm;
-  int32_t   lOutputPressure;
-  u16       uiFlowMaxInExpi;
-  int32_t lError = setPressure - uiProximalPressureMes;
-  
-  lIntegralTerm = (int32_t)Ki_Pressure_I * lError;  
-  if (Ki_Pressure_I<uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I]) 
-  {
-    Ki_Pressure_I++;
-  }
-          
-  // Close loop in pressure
-  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
-      lIntegral_Pressure_I = INTEGRAL_MAX;
-    else    
-      lIntegral_Pressure_I += lIntegralTerm;       
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
-      lIntegral_Pressure_I = INTEGRAL_MIN;
-    else
-      lIntegral_Pressure_I += lIntegralTerm;
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
-    lIntegral_Pressure_I += lIntegralTerm;
-  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
-    lIntegral_Pressure_I += lIntegralTerm;    
-       
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
-  
-  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
-   
-  lOutputPressure+=uiPWMatTheEndOfInspiration;
-  
-  // Flow limiting
-  uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
-  if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)
-  {      
-    // Impossible to maintain the peep (patient disconnection)
-    if (uiDisconnectionTime==0)
-    {        
-      if (fBlockCloseLoop==FALSE)
-        uiDisconnectionTimeInCPAP=CPAP_DISCONNECTION_TEST_PERIODICITY;
-      fBlockCloseLoop=TRUE;                                     // Block the close loop
-      if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
-        uiInspirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
-      else
-        uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-    else
-      uiDisconnectionTime--;  
-  }  
-  else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
-  {
-    // Good pressure : no disconnection
-    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;    
-    
-    if (fBlockCloseLoop==TRUE)
-    {
-      // The close loop was block before => unblock it
-      fBlockCloseLoop=FALSE;    
-      lIntegral_Pressure_I=0;
-      bMaxPIOutputPressureI = FALSE;
-      bMinPIOutputPressureI = FALSE;
-      uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;
-      return;
-    }
-    else if (iBlowerFlowSmoothingMes>=0)
-    {
-      // Record current PWM
-      uiMemoPWMDuringDisconnection=uiInspirationBlowerPWMTec;        
-    }
-  }
-        
-  // Unblock the close loop every 4s in case of none recorded PWM value
-  if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiDisconnectionTimeInCPAP==0) 
-  {
-    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
-    fBlockCloseLoop=FALSE;
-    lIntegral_Pressure_I=0;
-    bMaxPIOutputPressureI = FALSE;
-    bMinPIOutputPressureI = FALSE;
-    uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;
-    return;
-  }
-  
-  // Update Time counters 
-  if (uiDisconnectionTimeInCPAP!=0)
-    uiDisconnectionTimeInCPAP--;
-  
-  // Update blower PWM
-  if (fBlockCloseLoop==TRUE)
-  {      
-    bMaxPIOutputPressureI = TRUE; 
-  }
-  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-    {
-    bMaxPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-    }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-    {
-    bMinPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-  else
-    {
-    bMaxPIOutputPressureI = FALSE;
-    bMinPIOutputPressureI = FALSE;
-    uiInspirationBlowerPWMTec = lOutputPressure;
-    }
-      
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
-  
-}
-
-/*******************************************************************************
-* Function Name  : ManageOneCstPWM
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageOneCstPWM(void)
-{  
-  // *************************** UPDATE SETTINGS *******************************
-  if (ApplyNewVentilationMode()==TRUE)
-    return;
-  
-  // Update Blower Speed   
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
-}
-
-
-/*******************************************************************************
-* Function Name  : Manage2CstPWM
-* Description    : Manage Ti, Te, DAC, Blower, PID
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void Manage2CstPWM(void)
-{        
-  if (ucVentilationCycle==INSPIRATION_CYCLE)
-    {  
-    // ------------- INSPIRATION ------------      
-    SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
-    
-    // Inspiratoy time
-    uiTiD++;
-    if (uiTiD>=uiVentilationSet[TI_BARO_SET]) 
-      {
-      ucVentilationCycle=EXPIRATION_CYCLE;
-      uiTiD=0;
-      }
-    }
-  else
-    { 
-    // ------------- EXPIRATION ------------  
-    // *************************** UPDATE SETTINGS *******************************
-    if (ApplyNewVentilationMode()==TRUE)
-      return;
-    
-    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec); 
-        
-    // Expiratoy time
-    uiTeD++;
-    if (uiTeD>=uiTeBaroSet) 
-      {
-      ucVentilationCycle=INSPIRATION_CYCLE;
-      uiTeD=0;        
-      }
-    }
-}
-
-
-/*******************************************************************************
-* Function Name  : ManageCstSpeed
-* Description    : Manage constant speed ventilation
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageCstSpeed(void)
-{  
-  int32_t   lError;
-  int32_t   lPropTerm;                  
-  int32_t   lIntegralTerm;
-  int32_t   lOutputSpeed;
-  
-  // *************************** UPDATE SETTINGS *******************************
-  if (ApplyNewVentilationMode()==TRUE)
-    return;
-  
-  // Update settings
-  if (uiBlowerSpeedSetting<uiBlowerSpeedSet) 
-    uiBlowerSpeedSetting+=10;      
-  else if (uiBlowerSpeedSetting>uiBlowerSpeedSet) 
-    uiBlowerSpeedSetting-=10;      
-    
-  uiTiD++;
-  if ((uiTiD%10)==0)
-  {
-    // Barometric Mode : error computation
-    lError=(int32_t)uiBlowerSpeedSetting-(int32_t)uiBlowerSpeedMes;
-    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_SPEED_I_TEC] * lError;  
-            
-    // Close loop in pressure
-    if ((lIntegral_Speed_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputSpeedI==FALSE)) 
-      {
-      if ((lIntegral_Speed_I + lIntegralTerm) <0)
-        lIntegral_Speed_I = INTEGRAL_MAX;
-      else    
-        lIntegral_Speed_I += lIntegralTerm;       
-      }
-    else if ((lIntegral_Speed_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputSpeedI==FALSE)) 
-      {
-      if ((lIntegral_Speed_I + lIntegralTerm)>0)
-        lIntegral_Speed_I = INTEGRAL_MIN;
-      else
-        lIntegral_Speed_I += lIntegralTerm;
-      }
-    else if ((lIntegral_Speed_I<=0) && (lIntegralTerm>=0))
-      lIntegral_Speed_I += lIntegralTerm;
-    else if ((lIntegral_Speed_I>=0) && (lIntegralTerm<=0))    
-      lIntegral_Speed_I += lIntegralTerm;    
-         
-    lPropTerm = (int32_t)uiTechnicalDataSet[KP_SPEED_I_TEC] * lError;
-    lOutputSpeed = (lIntegral_Speed_I>>16) + (lPropTerm>>13);
-              
-    if (lOutputSpeed>=((int32_t)MAX_VOLTAGE_REF))
-      {
-      bMaxPIOutputSpeedI = TRUE; 
-      uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-      }
-    else if (lOutputSpeed<((int32_t)MIN_VOLTAGE_REF))
-      {
-      bMinPIOutputSpeedI = TRUE; 
-      uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-      }
-    else
-      {
-      bMaxPIOutputSpeedI = FALSE;
-      bMinPIOutputSpeedI = FALSE;
-      uiInspirationBlowerPWMTec = lOutputSpeed;
-      }
-    SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);   
-  }
-}
-
-/*******************************************************************************
-* Function Name  : ManageFlowCalibration
-* Description    : Manage Low flow calibration
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageFlowCalibration(void)
-{
-  char          cCharValue;
-  char          szTempBuf[SIZE_RX_BUFFER_PF300];
-  
-  /*  
-  #ifdef  USE_TSI_4040
-  switch(enTSICommScheduler)
-  {
-  default:
-  case TSI_SET_TYPE_OF_GAS:
-    {
-      // Send Type of Gas command                              
-      ucTSICommand=TSI_SEND_GAS_TYPE_AIR_CMD;
-      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
-      {
-        enTSICommScheduler=TSI_CHECK_ANSWER;
-        enTSIGoBackToStep=TSI_SET_FLOW_UNIT;                  
-      }
-      break;
-    }   
-  case TSI_SET_FLOW_UNIT:
-    {
-      // Send Type of Gas command                              
-      ucTSICommand=TSI_SEND_FLOW_UNIT_STANDARD_CMD;
-      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
-      {
-        enTSICommScheduler=TSI_CHECK_ANSWER;
-        enTSIGoBackToStep=TSI_SET_SAMPLE_TIME;                  
-      }
-      break;      
-    }  
-  case TSI_SET_SAMPLE_TIME:
-    {
-      // Send sample time
-      ucTSICommand=TSI_SEND_SAMPLE_TIME_10MS_CMD;
-      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
-      {
-        enTSICommScheduler=TSI_CHECK_ANSWER;
-        enTSIGoBackToStep=TSI_READ_FLOW;                  
-      }
-      break;      
-    }  
-  case TSI_READ_FLOW:
-    {
-      // Send sample time
-      ucTSICommand=TSI_SEND_READ_FLOW_CMD;
-      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
-      {
-        enTSICommScheduler=TSI_CHECK_ANSWER;
-        enTSIGoBackToStep=TSI_CYCLE_DETECTION;                  
-      }
-      break;      
-    } 
-  case TSI_CYCLE_DETECTION:
-    {
-      uiBlowerFlow=iFlowFromTSI;
-      break;
-    }
-  case TSI_CHECK_ANSWER:
-    {                      
-      opstatus=SS_Xgetw(tsi, &uiDummy);        
-      if (opstatus==OPSTATUS_OK)
-      {
-        enTSICommScheduler=enTSIGoBackToStep;
-      }
-      else if (opstatus==OPSTATUS_FAIL)
-      {
-        enTSICommScheduler=TSI_SET_TYPE_OF_GAS;
-      }        
-      break;  
-    }
-  }
-  #endif  // #ifdef  USE_TSI_4040
-  */
-    
-  switch(enLowFlowCalibrationStep)
-  {
-  case INIT_FLOW_CALIB_TEST:
-    {
-      // Init comm with PF300 => wait 2s before sending first command to PF300
-      // We need to wait for this delay in order to the handset to activate its transparent mode
-      if (uiCalibrationTimeOut==0)
-      {              
-        bDisableMaroubraCommCommunication=TRUE;
-        
-        // Prepare command to PF300 
-        UpdateBufferToSend((char*)szPF300_CmdSwitchOffEcho);       
-        enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;        
-        strcpy(szExpectedAnswerFromPF300, szPF300_AnswerSwitchOffEcho);
-        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerSwitchOffEcho);
-        enGoBackToStep=SET_GAS_TYPE;                  
-      } 
-      else
-      {
-        uiCalibrationTimeOut--;
-      }
-      break;
-    }   
-  case SET_GAS_TYPE:
-    {
-      // Prepare command to PF300 
-      UpdateBufferToSend((char*)szPF300_SetAirGasType);               
-      enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;      
-      strcpy(szExpectedAnswerFromPF300, szPF300_AnswerAirGasType);
-      ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerAirGasType);
-      enGoBackToStep=SET_GAS_STANDARD;  
-      break;      
-    }
-  case SET_GAS_STANDARD:
-    {
-      // Prepare command to PF300 
-      UpdateBufferToSend((char*)szPF300_SetGasStandard);             
-      enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;      
-      strcpy(szExpectedAnswerFromPF300, szPF300_AnswerGasStandard);
-      ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerGasStandard);
-      enGoBackToStep=START_FLOW_READING;  
-      break;      
-    }  
-  case START_FLOW_READING:
-    {
-      // Set Min blower speed
-      uiMotorDutyCyleForFlowCalib=MIN_PI_OUTPUT;
-      SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
-      
-      // Init variable for flow sensor
-      uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_FLOW;              
-      ulSumFlowTicks=0;
-      uiFlowTicksSamplesCounter=0;
-      
-      // Next step
-      enLowFlowCalibrationStep=SEND_FLOW_COMMAND;  
-      break;
-    }
-  case SEND_FLOW_COMMAND:
-    {      
-      if (uiCalibrationTimeOut!=0)
-      {
-        uiCalibrationTimeOut--;
-        
-        if (uiCalibrationTimeOut<(SAMPLE_RATE_BETWEEN_TWO_FLOW>>1))
-        {
-          ulSumFlowTicks+=uiBlowerFlowRAWMes;
-          uiFlowTicksSamplesCounter++;        
-        }
-      }
-      else
-      {
-        // Prepare next command (Read Low Flow)
-        enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;
-        if (bHighFlowCalibrationInProgress==FALSE)
-        {
-          UpdateBufferToSend((char*)szPF300_ReadLowFlowCmd);                // %RM#1\r      
-          strcpy(szExpectedAnswerFromPF300, szPF300_ReadLowFlowAnswer);     // %RM#1$          
-          ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadLowFlowAnswer);
-        }
-        else
-        {
-          UpdateBufferToSend((char*)szPF300_ReadHighFlowCmd);               // %RM#0\r      
-          strcpy(szExpectedAnswerFromPF300, szPF300_ReadHighFlowAnswer);    // %RM#0$          
-          ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadHighFlowAnswer);
-        }
-        enGoBackToStep=READ_FLOW_VALUE;                              
-      }
-      break;
-    }      
-  case READ_FLOW_VALUE: 
-    {                   
-      if (uiFlowTicksSamplesCounter!=0)
-      {
-        // Read PF300 flow (l/min)
-        strcpy(szTempBuf, &szAnswerFromPF300[ucNumberOfBytesToCheckFromPF300Answer]);
-        
-        // Store value of flow
-        if (stTemporayLUTFlowSensor.uiLUT_TableSize<LOW_FLOW_CALIB_NUMBER_OF_SAMPLES)
-          stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]=(unsigned int)atoi(szTempBuf);
-        else
-          stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]=(unsigned int)atoi(szTempBuf)*10;
-        
-        // Store ticks value
-        stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize]=ulSumFlowTicks/uiFlowTicksSamplesCounter;
-        uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_FLOW;        
-        ulSumFlowTicks=0; 
-        uiFlowTicksSamplesCounter=0;                                                
-                             
-        // Check if current flow <0.1l/min
-        if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<10)
-        {
-          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-          break;
-        }
-            
-        // Check if the last low flow is higher than 20l/min or lower than 2l/min
-        if (stTemporayLUTFlowSensor.uiLUT_TableSize==(LOW_FLOW_CALIB_NUMBER_OF_SAMPLES-1))
-        {
-          // Check if the last low flow is higher than 20l/min or lower than 2l/min
-          if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]>2000 || stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<200)
-          {
-            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-            break;
-          }
-        }
-        
-        // Next flow sample
-        if (stTemporayLUTFlowSensor.uiLUT_TableSize==LOW_FLOW_CALIB_NUMBER_OF_SAMPLES && stTemporayLUTFlowSensor.uiFlowValue[LOW_FLOW_CALIB_NUMBER_OF_SAMPLES]<(stTemporayLUTFlowSensor.uiFlowValue[LOW_FLOW_CALIB_NUMBER_OF_SAMPLES-1]+500))
-        {
-          // No enough flow margin between the last value of the low flow and the first value of the high flow
-        }             
-        else if (stTemporayLUTFlowSensor.uiLUT_TableSize!=0 && stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<(stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize-1]+50))
-        {
-          // No enough margin between two consecutives flow
-        }
-        else if (stTemporayLUTFlowSensor.uiLUT_TableSize!=0 && stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize]<=stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize-1])
-        {
-          // Same or less ticks between two consecutives flow
-          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-          break;
-        }
-        else
-        {
-          stTemporayLUTFlowSensor.uiLUT_TableSize++;
-          if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize-1]>=14000)
-          {
-            // End of calib => check the number of samples
-            if (stTemporayLUTFlowSensor.uiLUT_TableSize>(FLOW_CALIB_NUMBER_OF_SAMPLES>>1))
-            {
-              enLowFlowCalibrationStep=PREPARE_SUCCESS_COMMAND;
-              
-              // Transfer the temporary LUT in the definitive LUT
-              stLUTFlowSensor=stTemporayLUTFlowSensor;
-            }
-            else
-            {
-              enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-            }
-            break;
-          }
-          else if (stTemporayLUTFlowSensor.uiLUT_TableSize>FLOW_CALIB_NUMBER_OF_SAMPLES)
-          {             
-            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-            break;
-          }
-        }
-        
-        // Prepare next flow reading
-        if (stTemporayLUTFlowSensor.uiLUT_TableSize<LOW_FLOW_CALIB_NUMBER_OF_SAMPLES)
-        {
-          // New motor speed
-          uiMotorDutyCyleForFlowCalib+=20;
-          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;
-        }
-        else if (stTemporayLUTFlowSensor.uiLUT_TableSize==LOW_FLOW_CALIB_NUMBER_OF_SAMPLES && bHighFlowCalibrationInProgress==FALSE)
-        {
-          // Min speed for motor
-          uiMotorDutyCyleForFlowCalib=MIN_PI_OUTPUT;
-          SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
-          enLowFlowCalibrationStep=SEND_HIGH_FLOW_CALIB_REQUEST;          
-          break;
-        }
-        else
-        {
-          // New motor speed
-          uiMotorDutyCyleForFlowCalib+=10;
-          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;          
-        }
-        
-        // Update motor speed
-        if (uiMotorDutyCyleForFlowCalib<MAX_PI_OUTPUT)
-        {
-          SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
-        }
-        else
-        {
-          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-          break;
-        }                                        
-      }
-      else    // if (uiFlowTicksSamplesCounter!=0)
-      {
-        enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-      }            
-      break;
-    }
-  case SEND_HIGH_FLOW_CALIB_REQUEST:
-    {
-      if (TransferCommandToHandset((char*)szRequestHighFlowCalib)==TRUE)
-        enLowFlowCalibrationStep=WAIT_FOR_HIGH_FLOW_CALIB_ACK;       
-      break;
-    }
-  case WAIT_FOR_HIGH_FLOW_CALIB_ACK:
-    {
-      // Wait for acknownledge from handset
-      if (ReadByteReceive(&cCharValue)==TRUE)
-      {                          
-        if (cCharValue=='@')
-        {
-          // Continue flow calibration
-          bHighFlowCalibrationInProgress=TRUE;
-          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;
-        }
-        else
-          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-      }
-      break;
-    }
-  case PREPARE_FAILURE_COMMAND:
-    {
-      if (TransferCommandToHandset((char*)szEndOfCalibFailed)==TRUE)
-        enLowFlowCalibrationStep=END_OF_CALIBRATION;
-      break;
-    }
-  case PREPARE_SUCCESS_COMMAND:
-    {
-      if (TransferCommandToHandset((char*)szEndOfCalibOK)==TRUE)
-        enLowFlowCalibrationStep=END_OF_CALIBRATION;      
-      break;
-    }
-  case SEND_COMMAND_TO_PF300:
-    {
-      // Send a byte every 1ms
-      if (TransferBufferToPF300()==TRUE)
-      {      
-        // Buffer sent !!
-        if (ucNumberOfBytesToCheckFromPF300Answer!=0)
-        {
-          // Check answer from PF300
-          ucIndexAnswerFromPF300=0;
-          uiCalibrationTimeOut=TIME_OUT_RECEPTION_PACKET_FROM_PF300;
-          enLowFlowCalibrationStep=CHECK_COMMAND_FROM_PF300;
-        }
-        else
-          enLowFlowCalibrationStep=enGoBackToStep;
-      }
-      break;
-    }
-  case CHECK_COMMAND_FROM_PF300:
-    {
-      if (uiCalibrationTimeOut==0)
-      {
-        // Time-out in reception !!
-        ucIndexAnswerFromPF300=0;
-        enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-      }
-      else if (ReadByteReceive(&cCharValue)==TRUE)
-      {                            
-        // Check last byte received
-        if (cCharValue=='\r')
-        {
-          // End of answer => check buffer content
-          ucIndexAnswerFromPF300=0;
-          strcpy(szTempBuf, szAnswerFromPF300);
-          szTempBuf[ucNumberOfBytesToCheckFromPF300Answer]=0;
-          if (strcmp(szTempBuf, szExpectedAnswerFromPF300)==0)
-          {
-            // Buffer OK !!
-            enLowFlowCalibrationStep=enGoBackToStep;
-          }
-          else
-          {
-            // Buffer wrong !!
-            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-          }
-        }
-        else if (cCharValue=='?')
-        {
-          // PF300 is lost => end of calibration
-          ucIndexAnswerFromPF300=0;
-          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-        }                       
-        else
-        {
-          // Store byte from PF300 into buffer
-          szAnswerFromPF300[ucIndexAnswerFromPF300++]=cCharValue;
-          if (ucIndexAnswerFromPF300>=SIZE_RX_BUFFER_PF300)
-          {
-            // Answer too long !!
-            ucIndexAnswerFromPF300=0;
-            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
-          }
-          else
-          {
-            // Add 0 at the end of the string
-            szAnswerFromPF300[ucIndexAnswerFromPF300]=0; 
-          }
-        }
-      }
-      else
-      {
-        // No byte received !!
-        uiCalibrationTimeOut--;
-      }
-      break;  
-    }
-  default:  
-  case END_OF_CALIBRATION:
-    {      
-      uiTechnicalDataSet[START_STOP_VENTILATION]=0; 
-      bDisableMaroubraCommCommunication=FALSE;
-      break;
-    }
-  }         // switch
-  
-  // Every 300ms, send '@*' to inform the handset that the blower works properly
-  if (uiImHereMsgTimer==0)
-  {
-    if (enLowFlowCalibrationStep!=SEND_COMMAND_TO_PF300)
-    {
-      uiImHereMsgTimer=300;
-      TransferCommandToHandset((char*)szImHere);
-    }
-  }
-  else
-    uiImHereMsgTimer--;
-}
-
-/*******************************************************************************
-* Function Name  : ManagePressureCalibration
-* Description    : Manage pressure calibration
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManagePressureCalibration(void)
-{
-  char          cCharValue;
-  char          szTempBuf[SIZE_RX_BUFFER_PF300];
-  u16           uiCalibPressureADCValue;
-  u16           uiCalibPressureValue;
-  u16           uiCalibPressureGain;
-  
-  switch(enPressureCalibrationStep)
-  {
-  case INIT_PRESSURE_CALIB_TEST:
-    {
-      // Init comm with PF300 => wait 2s before sending first command to PF300
-      // We need to wait for this delay in order to the handset to activate its transparent mode
-      if (uiCalibrationTimeOut==0)
-      {              
-        bDisableMaroubraCommCommunication=TRUE;
-                                    
-        // Prepare command to PF300 
-        UpdateBufferToSend((char*)szPF300_CmdSwitchOffEcho);                     
-        strcpy(szExpectedAnswerFromPF300, szPF300_AnswerSwitchOffEcho);
-        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerSwitchOffEcho);
-        enPressureCalibrationStep=PRESSURE_CALIB_SEND_COMMAND_TO_PF300;  
-        enPressureCalibGoBackToStep=START_PRESSURE_READING;                  
-      } 
-      else
-      {
-        uiCalibrationTimeOut--;
-      }
-      break;
-    } 
-  case START_PRESSURE_READING:
-  {
-    // Set blower speed
-    SS_Xputdw(mdrv, 600);
-        
-    // Init variable for flow sensor
-    uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_PRESSURE;              
-    ulSumPressureTicks=0;
-    uiPressureTicksSamplesCounter=0;  
-    
-    enPressureCalibrationStep=SEND_PRESSURE_COMMAND;
-    break;
-  }
-  case SEND_PRESSURE_COMMAND:
-    {      
-      if (uiCalibrationTimeOut!=0)
-      {
-        uiCalibrationTimeOut--;
-        
-        if (uiCalibrationTimeOut<2000)
-        {
-          ulSumPressureTicks+=uiProximalPressureADCMes;
-          uiPressureTicksSamplesCounter++;        
-        }
-      }
-      else
-      {
-        // Prepare next command        
-        UpdateBufferToSend((char*)szPF300_ReadPdiffCmd);               
-        strcpy(szExpectedAnswerFromPF300, szPF300_ReadPdiffAnswer);    
-        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadPdiffAnswer);        
-        enPressureCalibrationStep=PRESSURE_CALIB_SEND_COMMAND_TO_PF300;
-        enPressureCalibGoBackToStep=READ_PRESSURE_VALUE;
-      }
-      break;
-    }      
-  case READ_PRESSURE_VALUE: 
-    {                   
-      if (uiPressureTicksSamplesCounter!=0)
-      {
-        // Read PF300 pressure
-        strcpy(szTempBuf, &szAnswerFromPF300[ucNumberOfBytesToCheckFromPF300Answer]);
-        
-        // Store value of Pressure        
-        uiCalibPressureValue=(unsigned int)atoi(szTempBuf);
-        
-        // Store ticks value
-        uiCalibPressureADCValue=ulSumPressureTicks/uiPressureTicksSamplesCounter;
-        uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_PRESSURE;        
-        ulSumPressureTicks=0; 
-        uiPressureTicksSamplesCounter=0;                                                
-                             
-        // Check if current pressure<10cmH20
-        if (uiCalibPressureValue<1000)
-        {
-          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-          break;
-        }
-            
-        // Compute pressure gain
-        uiCalibPressureGain=(10000UL*(uiCalibPressureADCValue-uiTechnicalDataSet[PPROX_OFFSET_TEC]))/uiCalibPressureValue; 
-        uiCalibPressureGain+=5;
-        uiCalibPressureGain/=10;
-        
-        // Check pressure gain range  
-        if (uiCalibPressureGain<Tec_GainPprox_MIN || uiCalibPressureGain>Tec_GainPprox_MAX)
-        {
-          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-        }
-        else
-        {
-          enPressureCalibrationStep=PRESSURE_CALIB_SUCCESS_COMMAND;
-          
-          // Transfer the temporary LUT in the definitive LUT
-          uiTechnicalDataSet[PPROX_GAIN_TEC]=uiCalibPressureGain;
-        }                                  
-      }
-      else    // if (uiPressureTicksSamplesCounter!=0)
-      {
-        enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-      }            
-      break;
-    }  
-  case PRESSURE_CALIB_FAILURE_COMMAND:
-    {
-      if (TransferCommandToHandset((char*)szEndOfCalibFailed)==TRUE)
-        enPressureCalibrationStep=PRESSURE_CALIB_END_OF_CALIBRATION;
-      break;
-    }
-  case PRESSURE_CALIB_SUCCESS_COMMAND:
-    {
-      if (TransferCommandToHandset((char*)szEndOfCalibOK)==TRUE)
-        enPressureCalibrationStep=PRESSURE_CALIB_END_OF_CALIBRATION;      
-      break;
-    }
-  case PRESSURE_CALIB_SEND_COMMAND_TO_PF300:
-    {
-      // Send a byte every 1ms
-      if (TransferBufferToPF300()==TRUE)
-      {      
-        // Buffer sent !!
-        if (ucNumberOfBytesToCheckFromPF300Answer!=0)
-        {
-          // Check answer from PF300
-          ucIndexAnswerFromPF300=0;
-          uiCalibrationTimeOut=TIME_OUT_RECEPTION_PACKET_FROM_PF300;
-          enPressureCalibrationStep=PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300;
-        }
-        else
-          enPressureCalibrationStep=enPressureCalibGoBackToStep;
-      }
-      break;
-    }
-  case PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300:
-    {
-      if (uiCalibrationTimeOut==0)
-      {
-        // Time-out in reception !!
-        ucIndexAnswerFromPF300=0;
-        enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-      }
-      else if (ReadByteReceive(&cCharValue)==TRUE)
-      {                            
-        // Check last byte received
-        if (cCharValue=='\r')
-        {
-          // End of answer => check buffer content
-          ucIndexAnswerFromPF300=0;
-          strcpy(szTempBuf, szAnswerFromPF300);
-          szTempBuf[ucNumberOfBytesToCheckFromPF300Answer]=0;
-          if (strcmp(szTempBuf, szExpectedAnswerFromPF300)==0)
-          {
-            // Buffer OK !!
-            enPressureCalibrationStep=enPressureCalibGoBackToStep;
-          }
-          else
-          {
-            // Buffer wrong !!
-            enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-          }
-        }
-        else if (cCharValue=='?')
-        {
-          // PF300 is lost => end of calibration
-          ucIndexAnswerFromPF300=0;
-          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-        }                       
-        else
-        {
-          // Store byte from PF300 into buffer
-          szAnswerFromPF300[ucIndexAnswerFromPF300++]=cCharValue;
-          if (ucIndexAnswerFromPF300>=SIZE_RX_BUFFER_PF300)
-          {
-            // Answer too long !!
-            ucIndexAnswerFromPF300=0;
-            enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
-          }
-          else
-          {
-            // Add 0 at the end of the string
-            szAnswerFromPF300[ucIndexAnswerFromPF300]=0; 
-          }
-        }
-      }
-      else
-      {
-        // No byte received !!
-        uiCalibrationTimeOut--;
-      }
-      break;  
-    }
-  default:  
-  case PRESSURE_CALIB_END_OF_CALIBRATION:
-    {      
-      uiTechnicalDataSet[START_STOP_VENTILATION]=0; 
-      bDisableMaroubraCommCommunication=FALSE;
-      break;
-    }
-  }         // switch
-  
-  // Every 300ms, send '@*' to inform the handset that the blower works properly
-  if (uiImHereMsgTimer==0)
-  {
-    if (enPressureCalibrationStep!=PRESSURE_CALIB_SEND_COMMAND_TO_PF300)
-    {
-      uiImHereMsgTimer=300;
-      TransferCommandToHandset((char*)szImHere);
-    }
-  }
-  else
-    uiImHereMsgTimer--;
-}
-
-
-/*******************************************************************************
-* Function Name  : ManageCstPressure
-* Description    : Manage constant pressure
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageCstPressure(void)
-{
-  int32_t   lError;
-  int32_t   lPropTerm;                  
-  int32_t   lIntegralTerm;
-  int32_t   lOutputPressure;
-
-  
-  // Barometric Mode : error computation
-  lError=(int32_t)uiMLT_PressureSetPoint-(int32_t)uiProximalPressureMes;
-  lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I] * lError;  
-  if (uiMLT_PressureSetPoint<uiVentilationSet[PI_SET]) uiMLT_PressureSetPoint++;
-             
-  // Close loop in pressure
-  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
-      lIntegral_Pressure_I = INTEGRAL_MAX;
-    else    
-      lIntegral_Pressure_I += lIntegralTerm;       
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
-      lIntegral_Pressure_I = INTEGRAL_MIN;
-    else
-      lIntegral_Pressure_I += lIntegralTerm;
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
-    lIntegral_Pressure_I += lIntegralTerm;
-  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
-    lIntegral_Pressure_I += lIntegralTerm;    
-    
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
-  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
-
-  // Add constante value (PWM at the end of the previous inspiration)    
-  //lOutputPressure+=300; 
-   
-  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-  {
-    bMaxPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-  }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-  {
-    bMinPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-  }
-  else
-  {
-    bMaxPIOutputPressureI = FALSE;
-    bMinPIOutputPressureI = FALSE;
-    uiInspirationBlowerPWMTec = lOutputPressure;
-  }
-    
-  // Update Blower Speed   
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);     
-  
-  // Monitoring and Alarm (every 1s)
-  #ifdef MOTOR_LIFE_TESTING
-    if (uiAverageMonitoringMLT==0)
-    {
-      uiAverageBlowerSpeedMes=ulMLT_SumSpeedMes/MLT_AVERAGE_MONITORING;
-      uiBreathBlowerCurrentMes=ulMLT_SumCurrentMes/MLT_AVERAGE_MONITORING;
-      uiAverateMotorTempMes=ulMLT_SumTemperatureMes/MLT_AVERAGE_MONITORING;
-      uiAverageMotorVoltage=ulMLT_SumBlowerVoltage/MLT_AVERAGE_MONITORING;
-      
-      ulMLT_SumSpeedMes=0;
-      ulMLT_SumCurrentMes=0;
-      ulMLT_SumTemperatureMes=0;
-      ulMLT_SumBlowerVoltage=0;
-      uiAverageMonitoringMLT=MLT_AVERAGE_MONITORING;
-    }
-    else
-    {
-      ulMLT_SumSpeedMes+=uiBlowerSpeedMes;
-      ulMLT_SumCurrentMes+=uiBlowerCurrentMes;
-      ulMLT_SumTemperatureMes+=uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES];
-      ulMLT_SumBlowerVoltage+=uiTechnicalDataMes[MOTOR_VOLTAGE_TEC_MES];
-      uiAverageMonitoringMLT--;
-    }
-    
-    // Alarms management
-    if (uiMLT_EnableAlarm==0)
-    {
-      // High Speed alarm
-      if (uiAverageBlowerSpeedMes>uiTechnicalDataSet[MLT_HIGH_SPEED_TEC])
-        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_SPEED_ALARM_MASK;
-      
-      // Low Speed alarm
-      if (uiAverageBlowerSpeedMes<uiTechnicalDataSet[MLT_LOW_SPEED_TEC])
-        uiFlagsAlarm[ALARM_FLAGS2]|=LOW_BLOWER_SPEED_ALARM_MASK;
-        
-      // High blower current alarm
-      if (uiBreathBlowerCurrentMes>uiTechnicalDataSet[MLT_HIGH_CURRENT_TEC])
-        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_CURRENT_ALARM_MASK;
-      
-      // High Blower temperature
-      if (uiAverateMotorTempMes>uiTechnicalDataSet[MLT_HIGH_TEMPERATURE_TEC])
-        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_TEMP_ALARM_MASK;
-
-      // Low Blower temperature
-      if (uiAverateMotorTempMes<100)
-        uiFlagsAlarm[ALARM_FLAGS2]|=LOW_BLOWER_TEMP_ALARM_MASK;
-      
-      // High Blower Flow
-      if (iBlowerFlowSmoothingMesForTrigger>uiTechnicalDataSet[MLT_HIGH_FLOW_TEC] || iBlowerFlowSmoothingMesForTrigger<uiTechnicalDataSet[MLT_LOW_FLOW_TEC])
-        uiFlagsAlarm[ALARM_FLAGS2]|=OOR_BLOWER_FLOW_ALARM_MASK;
-    }
-    else
-      uiMLT_EnableAlarm--;
-  #endif  // MOTOR_LIFE_TESTING
-}
-
-
-/*******************************************************************************
-* Function Name  : ManagePACVVentilation
-* Description    : Manage Bilevel ventilation
-* Input          : bPSMode=true in PS mode, false in PI mode
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManagePACVVentilation(bool bPSMode)
-{
-int32_t   lError;
-int32_t   lPropTerm;                  
-int32_t   lIntegralTerm;
-int32_t   lOutputPressure;
-u16       uiPressureSetPoint;
-u16       uiTiMax;
-u16       uiTiMin;
-//u16       uiTeMax;
-u16       uiFlowMaxInExpi;
-
-if (ucVentilationCycle==INSPIRATION_CYCLE)
-  {  
-  // ---------------------------------------------------------------------------
-  // -                              INSPIRATION                                -
-  // --------------------------------------------------------------------------              
-                  
-  // Ti et pressure set point management
-  if (bPSMode==TRUE)   
-  {
-    uiPressureSetPoint=uiVentilationSet[PS_SET]; 
-    uiTiMax=uiVentilationSet[TI_MAX_SET]; 
-  }
-  else    
-  {
-    uiPressureSetPoint=uiVentilationSet[PI_SET];
-    uiTiMax=uiVentilationSet[TI_BARO_SET];    
-  }
-  
-  // Compute Timin
-  if (uiPatientType==PATIENT_ADULT)   
-    uiTiMin=TiBaroSet_A_MIN;
-  else
-    uiTiMin=TiBaroSet_P_MIN;
-   
-  // Limit the pressure setting
-  if (uiVentilationSet[HIGH_PRESSURE_ALARM_SET]<uiPressureSetPoint)
-    uiPressureSetPoint=uiVentilationSet[HIGH_PRESSURE_ALARM_SET];
-  
-  if (uiTiD==0) 
-  { 
-    // Management Expiratory Trigger    
-    ucTempoTriggerExpiAuto=TEMPO_TRIGGER_EXPI;
-    ucExpiTriggerTreshold=MIN_THRESHOLD_EXPI_TRIGGER_AUTO;
-    
-    // Management Inspiratory slope    
-    switch(uiVentilationSet[SLOPE_BARO_SET])
-    {
-      default:
-      case 1:
-      {
-        // Slope of 5ms/hPa => 0.2hPa/ms
-        uiIpapSettingTemp=uiVentilationSet[PEEP_SET]+2;                    
-        break;
-      }
-      case 2:
-      {
-        ucIndexTableSlope=0;
-        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope2Table[ucIndexTableSlope++])/100;
-        break;
-      }
-      case 3:
-      {
-        ucIndexTableSlope=0;
-        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope3Table[ucIndexTableSlope++])/100;
-        break;
-      }
-      case 4:
-      {
-        ucIndexTableSlope=0;
-        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope4Table[ucIndexTableSlope++])/100;
-        break;
-      }
-    }
-  }
-  else 
-  {
-    // Management Inspiratory slope 
-    switch(uiVentilationSet[SLOPE_BARO_SET])
-    {
-      default:
-      case 1:
-      {
-        // Slope of 5ms/hPa => 0.2hPa/ms
-        uiIpapSettingTemp+=2;                                   
-        if (uiIpapSettingTemp>uiPressureSetPoint) 
-          uiIpapSettingTemp=uiPressureSetPoint;
-        break;
-      }
-      case 2:
-      {
-        if (ucIndexTableSlope<SIZE_SLOPE2_TABLE && (uiTiD%10)==0)
-          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope2Table[ucIndexTableSlope++])/100;
-        break;
-      }
-      case 3:
-      {
-        if (ucIndexTableSlope<SIZE_SLOPE3_TABLE && (uiTiD%10)==0)
-          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope3Table[ucIndexTableSlope++])/100;
-        break;
-      }
-      case 4:
-      {
-        if (ucIndexTableSlope<SIZE_SLOPE4_TABLE && (uiTiD%10)==0)
-          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope4Table[ucIndexTableSlope++])/100;
-        break;
-      }
-    }        
-  }     
-  
-  // Barometric Mode : error computation
-  lError=(int32_t)uiIpapSettingTemp-(int32_t)uiProximalPressureMes;
-  if (fFirstCycleInspi==FALSE) 
-    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_I] * lError;
-  else
-  {
-    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_I]>>2) * lError;
-    uiPWMatTheEndOfInspiration=uiExpirationBlowerPWMTec;
-  }
-             
-  // Close loop in pressure
-  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
-      lIntegral_Pressure_I = INTEGRAL_MAX;
-    else    
-      lIntegral_Pressure_I += lIntegralTerm;       
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
-    {
-    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
-      lIntegral_Pressure_I = INTEGRAL_MIN;
-    else
-      lIntegral_Pressure_I += lIntegralTerm;
-    }
-  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
-    lIntegral_Pressure_I += lIntegralTerm;
-  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
-    lIntegral_Pressure_I += lIntegralTerm;    
-    
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_I] * lError;
-  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
-
-  // Add constante value (PWM at the end of the previous inspiration)    
-  lOutputPressure+=uiPWMatTheEndOfInspiration; 
-   
-  if (fAlarmPmax==TRUE || fAlarmVtiMax==TRUE)
-  {
-    bMaxPIOutputPressureI = TRUE; 
-  }
-  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-  {
-    bMaxPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-  }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-  {
-    bMinPIOutputPressureI = TRUE; 
-    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-  }
-  else
-  {
-    bMaxPIOutputPressureI = FALSE;
-    bMinPIOutputPressureI = FALSE;
-    uiInspirationBlowerPWMTec = lOutputPressure;
-  }
-    
-  // Update Blower Speed   
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);                                  
-              
-  // ************************ CYCLE MANAGEMENT *********************************
-  uiTiD++; 
-  if ((uiTiD>=uiTiMax) || 
-      (TestTriggerExpiratoire(uiVentilationSet[TRIG_E_SET], uiVentilationSet[PS_SET])==TRUE && uiTiD>uiVentilationSet[TI_MIN_SET] && bPSMode==TRUE) ||
-      (fAlarmPmax==TRUE   && uiTiD>uiTiMin) ||
-      (fAlarmVtiMax==TRUE && uiTiD>uiTiMin))
-    {   
-    // Beginning of the expiration  
-    if (fAlarmPmax==FALSE && fAlarmVtiMax==FALSE)
-    {
-      fFirstCycleInspi=FALSE;
-      uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;  
-    }
-    else
-    {
-      fFirstCycleInspi=TRUE;
-      uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;
-    }
-    
-    ucVentilationCycle=EXPIRATION_CYCLE;
-    uiTiD=0;                              
-             
-    // Reset PI variables for next inspiration
-    lIntegral_Pressure_E=0;         
-    bMaxPIOutputPressureE=FALSE;
-    bMinPIOutputPressureE=FALSE;   
-    
-    fFirstCycleExpi=FALSE;     
-    }
-  }  
-else
-  { 
-  // ---------------------------------------------------------------------------
-  // -                               EXPIRATION                                -
-  // ---------------------------------------------------------------------------                    
-  
-  // *************************** UPDATE SETTINGS *******************************
-  if (ApplyNewVentilationMode()==TRUE)
-    return;
-      
-  // ******************** MAIN BLOWER MANAGEMENT *******************************  
-  if (uiVentilationSet[PEEP_SET]==0)
-  {
-    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
-  }
-  else
-  {
-    if (uiTeD==0) 
-    {         
-      // First blower current setting
-      uiEpapSettingTemp=uiVentilationSet[PI_SET]-2;                    // Slope of 5ms/hPa => 0.2hPa/ms
-    }
-    else 
-    {
-      // we increase the speed of the blower every 1ms        
-      uiEpapSettingTemp-=2;                           // Slope of 5ms/hPa => 0.2hPa/ms
-      if (uiEpapSettingTemp<uiVentilationSet[PEEP_SET]) 
-        uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
-    } 
-    
-    // Barometric Mode : error computation
-    if (fFirstCycleExpi==FALSE)    
-    {
-      lError=(int32_t)uiEpapSettingTemp-(int32_t)uiProximalPressureMes;
-      lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_E] * lError;   
-    }
-    else    
-    {
-      lError=(int32_t)uiVentilationSet[PEEP_SET]-(int32_t)uiProximalPressureMes;
-      lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_E]>>2) * lError;   
-    }  
-             
-    // Close loop in pressure    
-    if ((lIntegral_Pressure_E>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureE==FALSE)) 
-    {
-      if ((lIntegral_Pressure_E + lIntegralTerm) <0)
-        lIntegral_Pressure_E = INTEGRAL_MAX;
-      else    
-        lIntegral_Pressure_E += lIntegralTerm;       
-    }
-    else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureE==FALSE)) 
-    {
-      if ((lIntegral_Pressure_E + lIntegralTerm)>0)
-        lIntegral_Pressure_E = INTEGRAL_MIN;
-      else
-        lIntegral_Pressure_E += lIntegralTerm;
-    }
-    else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm>=0))
-      lIntegral_Pressure_E += lIntegralTerm;
-    else if ((lIntegral_Pressure_E>=0) && (lIntegralTerm<=0))    
-      lIntegral_Pressure_E += lIntegralTerm;    
-      
-    lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_E] * lError;
-    lOutputPressure = (lIntegral_Pressure_E>>16) + (lPropTerm>>13);
-  
-    // Add constante value (PWM at the end of the previous expiration)    
-    lOutputPressure+=uiPWMatTheEndOfExpiration; 
-           
-    // Flow limiting
-    uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
-    if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)     
-    {  
-      // Impossible to maintain the peep (patient disconnection)
-      if (uiDisconnectionTime==0)
-      {        
-        fBlockCloseLoop=TRUE;                                     // Block the close loop
-        if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
-          uiExpirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
-        else
-          uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-      }
-      else
-        uiDisconnectionTime--;      
-    }   
-    else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
-    {             
-      // Good pressure : no disconnection 
-      uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;                       
-      if (fBlockCloseLoop==TRUE)
-      {
-        // The close loop was block before => unblock it
-        fBlockCloseLoop=FALSE;    
-        lIntegral_Pressure_E=0;
-        bMaxPIOutputPressureE = FALSE;
-        bMinPIOutputPressureE = FALSE;
-        lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
-      }
-      else if (iBlowerFlowSmoothingMes>=0)
-      {
-        // Record current PWM
-        uiMemoPWMDuringDisconnection=uiExpirationBlowerPWMTec;        
-      }
-    }    
-          
-    // Unblock the close loop every 4s in case of none recorded PWM value
-    if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiTeD==0)
-    {
-      uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
-      fBlockCloseLoop=FALSE;
-      lIntegral_Pressure_E=0;
-      bMaxPIOutputPressureE = FALSE;
-      bMinPIOutputPressureE = FALSE;
-      lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
-    }
-        
-    // Update blower PWM
-    if (fBlockCloseLoop==TRUE)
-    {      
-      bMaxPIOutputPressureE = TRUE; 
-    }
-    else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-    {
-      bMaxPIOutputPressureE = TRUE; 
-      uiExpirationBlowerPWMTec=MAX_VOLTAGE_REF;
-    }
-    else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-    {
-      bMinPIOutputPressureE = TRUE; 
-      uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-    else
-    {
-      bMaxPIOutputPressureE = FALSE;
-      bMinPIOutputPressureE = FALSE;
-      uiExpirationBlowerPWMTec = lOutputPressure;
-    }       
-    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                            
-  }
-           
-  // Expiratory time
-  uiTeD++;
-  if (uiTeD>TE_SET_MAX) uiTeD=TE_SET_MAX;
-  if ((uiTeD>=uiTeBaroSet && bPSMode==FALSE) || TestInspiratoryTrigger(bPSMode, uiTeD, uiVentilationSet[TRIG_I_FLOW_SET])==TRUE)
-    {
-    ucVentilationCycle=INSPIRATION_CYCLE;
-    uiTeD=0;         
-      
-    // Record PWM value at the end of the expiration
-    uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;    
-          
-    // Reset PI variables for next inspiration
-    lIntegral_Pressure_I=0;         
-    bMaxPIOutputPressureI=FALSE;
-    bMinPIOutputPressureI=FALSE;
-    }
-  }  
-}
-
-
-
-/*******************************************************************************
-* Function Name  : ManageVolumetricVentilation
-* Description    : Manage Volumetric Ventilation
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ManageVolumetricVentilation(void)
-{
-int32_t   lError;
-int32_t   lPropTerm;                  
-int32_t   lIntegralTerm;
-int32_t   lOutputPressure;
-int16_t   iMaxVtAdjust;
-u16       uiFlowMaxInExpi;
-u16       uiTiMin;
-
-if (ucVentilationCycle==INSPIRATION_CYCLE)
-  {  
-  // ---------------------------------------------------------------------------
-  // -                              INSPIRATION                                -
-  // ---------------------------------------------------------------------------             
-                
-  // Compute Timin
-  if (uiPatientType==PATIENT_ADULT)   
-    uiTiMin=TiVoluSet_A_MIN;
-  else
-    uiTiMin=TiVoluSet_P_MIN;
-  
-  // ************************** Main Blower MANAGEMENT *************************        
-  if (uiTiD==0) 
-  { 
-    // Compute Volume adjustment
-    if (fFirstCycleInspi==FALSE)
-    {
-      if ((uiFlagsAlarm[ALARM_FLAGS1]&HIGH_PRESSURE_ALARM_MASK)==0)
-      {
-        if (ucCounterHPAlarm==0)
-        {
-          iVtAdjust+=(((int16_t)uiVentilationSet[VT_SET]-(int16_t)uiRecordVtiMes>>1));
-          if (iVtAdjust>0)
-          {
-            iMaxVtAdjust=(int16_t)(uiVentilationSet[VT_SET]>>1);        // >0
-            if (iVtAdjust>iMaxVtAdjust)
-              iVtAdjust=iMaxVtAdjust;        
-          }
-          else if (iVtAdjust<0)
-          {
-            iMaxVtAdjust=(int16_t)(~(uiVentilationSet[VT_SET]>>1)+1);  // <0
-            if (iVtAdjust<iMaxVtAdjust)
-              iVtAdjust=iMaxVtAdjust;                
-          }
-        }
-        else
-          ucCounterHPAlarm--;
-      }
-      else
-        ucCounterHPAlarm=1;
-    }
-    else    
-      iVtAdjust=0;   
-    
-    ComputeInspiratoryFlowSetPointInAVC(uiPatientType, (u16)((int16_t)uiVentilationSet[VT_SET]+iVtAdjust), uiVentilationSet[TI_VOLU_SET], uiVentilationSet[SHAPE_SET], &ulMaxIFlowSet, &ulMinIFlowSet, &ulDecFlowStep);    
-  }
-  else
-  {
-    if (ulMaxIFlowSet>=ulDecFlowStep)
-      ulMaxIFlowSet-=ulDecFlowStep;
-    if (ulMaxIFlowSet<ulMinIFlowSet)
-      ulMaxIFlowSet=ulMinIFlowSet;
-  }
-    
-  // Volumetric Mode : error computation
-  //lError=(int32_t)(ulMaxIFlowSet/100)-iBlowerFlowMes;
-  lError=(int32_t)(ulMaxIFlowSet/100)-iBlowerFlowSmoothingMes;
-  if (fFirstCycleInspi==FALSE)
-  {
-    if (ulMaxIFlowSet<150000 && uiTiD>30000)
-      lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_FLOW_I]>>1) * lError;
-    else
-      lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_FLOW_I] * lError;
-  }
-  else
-    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_FLOW_I]>>2) * lError;
-             
-  // Close loop in pressure or flow (PI)
-  if ((lIntegral_Flow_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputFlowI==FALSE)) 
-    {
-    if ((lIntegral_Flow_I + lIntegralTerm) <0)
-      lIntegral_Flow_I = INTEGRAL_MAX;
-    else    
-      lIntegral_Flow_I += lIntegralTerm;       
-    }
-  else if ((lIntegral_Flow_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputFlowI==FALSE)) 
-    {
-    if ((lIntegral_Flow_I + lIntegralTerm)>0)
-      lIntegral_Flow_I = INTEGRAL_MIN;
-    else
-      lIntegral_Flow_I += lIntegralTerm;
-    }
-  else if ((lIntegral_Flow_I<=0) && (lIntegralTerm>=0))
-    lIntegral_Flow_I += lIntegralTerm;
-  else if ((lIntegral_Flow_I>=0) && (lIntegralTerm<=0))    
-    lIntegral_Flow_I += lIntegralTerm;    
-    
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_FLOW_I] * lError;
-  lOutputPressure = (lIntegral_Flow_I>>16) + (lPropTerm>>13);
-
-  // Add constante value (PWM at the end of the previous inspiration)    
-  lOutputPressure+=uiPWMatTheEndOfExpiration; 
-    
-  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-    {
-    bMaxPIOutputFlowI = TRUE; 
-    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
-    }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-    {
-    bMinPIOutputFlowI = TRUE; 
-    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-  else
-    {
-    bMaxPIOutputFlowI = FALSE;
-    bMinPIOutputFlowI = FALSE;
-    uiInspirationBlowerPWMTec = lOutputPressure;
-    }
-    
-  // Update Blower Speed   
-  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);                                  
-              
-  // ************************ CYCLE MANAGEMENT *********************************
-  uiTiD++; 
-  if ((uiTiD>=uiVentilationSet[TI_VOLU_SET]) ||
-      (fAlarmPmax==TRUE && uiTiD>uiTiMin))
-    {   
-    // Beginning of the expiration      
-    uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;            
-    uiProximalPressureAtTheEndOfInspiration=uiProximalPressureMes;
-      
-    ucVentilationCycle=EXPIRATION_CYCLE;
-    uiTiD=0;                              
-             
-    // Reset PI variables for next inspiration
-    lIntegral_Pressure_E=0;         
-    bMaxPIOutputPressureE=FALSE;
-    bMinPIOutputPressureE=FALSE;   
-    
-    fFirstCycleExpi=FALSE;  
-    fFirstCycleInspi=FALSE;
-    }
-  }  
-else
-  { 
-  // ---------------------------------------------------------------------------
-  // -                               EXPIRATION                                -
-  // ---------------------------------------------------------------------------                    
-  
-  // *************************** UPDATE SETTINGS *******************************
-  if (ApplyNewVentilationMode()==TRUE)
-    return;
-  
-  // ******************** MAIN BLOWER MANAGEMENT *******************************  
-  if (uiVentilationSet[PEEP_SET]==0)
-  {
-    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
-  }
-  else
-  {
-  if (uiTeD==0) 
-    {         
-    // First blower pressure setting
-    if (uiProximalPressureAtTheEndOfInspiration<uiVentilationSet[PEEP_SET])
-      uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
-    else if (uiProximalPressureAtTheEndOfInspiration>=2)
-      uiEpapSettingTemp=uiProximalPressureAtTheEndOfInspiration-2;  // Slope of 5ms/hPa => 0.2hPa/ms
-    else
-      uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
-    }
-  else 
-    {
-    // we decrease the speed of the blower every 1ms  
-    if (uiEpapSettingTemp>=2)      
-      uiEpapSettingTemp-=2;                           // Slope of 5ms/hPa => 0.2hPa/ms    
-    } 
-    
-  // Pressure set point limitation
-  if (uiEpapSettingTemp<uiVentilationSet[PEEP_SET]) 
-    uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
-  
-  // Barometric Mode : error computation
-  if (fFirstCycleExpi==FALSE)    
-  {
-    lError=(int32_t)uiEpapSettingTemp-(int32_t)uiProximalPressureMes;
-    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_E] * lError;   
-  }
-  else    
-  {
-    lError=(int32_t)uiVentilationSetTemp[PEEP_SET]-(int32_t)uiProximalPressureMes;
-    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_E]>>2) * lError;   
-  }  
-             
-  // Close loop in pressure
-  if ((lIntegral_Pressure_E>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureE==FALSE)) 
-  {
-    if ((lIntegral_Pressure_E + lIntegralTerm) <0)
-      lIntegral_Pressure_E = INTEGRAL_MAX;
-    else    
-      lIntegral_Pressure_E += lIntegralTerm;       
-  }
-  else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureE==FALSE)) 
-  {
-    if ((lIntegral_Pressure_E + lIntegralTerm)>0)
-      lIntegral_Pressure_E = INTEGRAL_MIN;
-    else
-      lIntegral_Pressure_E += lIntegralTerm;
-  }
-  else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm>=0))
-    lIntegral_Pressure_E += lIntegralTerm;
-  else if ((lIntegral_Pressure_E>=0) && (lIntegralTerm<=0))    
-    lIntegral_Pressure_E += lIntegralTerm;    
-    
-  lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_E] * lError;
-  lOutputPressure = (lIntegral_Pressure_E>>16) + (lPropTerm>>13);
-
-  // Add constante value (PWM at the end of the previous expiration)    
-  lOutputPressure+=uiPWMatTheEndOfExpiration; 
-  
-  // Flow limiting
-  uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
-  if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)     
-  {  
-    // Impossible to maintain the peep (patient disconnection)
-    if (uiDisconnectionTime==0)
-    {        
-      fBlockCloseLoop=TRUE;                                     // Block the close loop
-      if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
-        uiExpirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
-      else
-        uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-    }
-    else
-      uiDisconnectionTime--;      
-  }   
-  else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
-  {             
-    // Good pressure : no disconnection 
-    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;                       
-    if (fBlockCloseLoop==TRUE)
-    {
-      // The close loop was block before => unblock it
-      fBlockCloseLoop=FALSE;    
-      lIntegral_Pressure_E=0;
-      bMaxPIOutputPressureE = FALSE;
-      bMinPIOutputPressureE = FALSE;
-      lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
-    }
-    else if (iBlowerFlowSmoothingMes>=0)
-    {
-      // Record current PWM
-      uiMemoPWMDuringDisconnection=uiExpirationBlowerPWMTec;        
-    }
-  }    
-        
-  // Unblock the close loop every 4s in case of none recorded PWM value
-  if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiTeD==0)
-  {
-    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
-    fBlockCloseLoop=FALSE;
-    lIntegral_Pressure_E=0;
-    bMaxPIOutputPressureE = FALSE;
-    bMinPIOutputPressureE = FALSE;
-    lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
-  }
-  
-  // Update blower PWM
-  if (fBlockCloseLoop==TRUE)
-  {      
-    bMaxPIOutputPressureE = TRUE; 
-  }  
-  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
-  {
-    bMaxPIOutputPressureE = TRUE; 
-    uiExpirationBlowerPWMTec=MAX_VOLTAGE_REF;
-  }
-  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
-  {
-    bMinPIOutputPressureE = TRUE; 
-    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
-  }
-  else
-  {
-    bMaxPIOutputPressureE = FALSE;
-    bMinPIOutputPressureE = FALSE;
-    uiExpirationBlowerPWMTec = lOutputPressure;
-  }    
-  // Update Blower Speed   
-  SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
-  }
-  
-  // Expiratory time
-  uiTeD++;
-  if (uiTeD>=uiTeVoluSet || TestInspiratoryTrigger(FALSE, uiTeD, uiVentilationSet[TRIG_I_FLOW_SET])==TRUE)
-    {
-    ucVentilationCycle=INSPIRATION_CYCLE;
-    uiTeD=0;         
-      
-    // Record PWM value at the end of the expiration
-    if (fBlockCloseLoop==FALSE)
-      uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
-    else
-      uiPWMatTheEndOfExpiration=0;
-    fBlockCloseLoop=FALSE; 
-    
-    // Reset PI variables for next inspiration
-    lIntegral_Flow_I=0;         
-    bMaxPIOutputFlowI=FALSE;
-    bMinPIOutputFlowI=FALSE;
-    }
-  }  
-}
-
-
-
-/*******************************************************************************
-* Function Name  : LaunchTherapyEngine
-* Description    : Select and launch the therapy engine
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void LaunchTherapyEngine(void)
-{
-  if (bMemoStartVentilation==TRUE)
-  {
-    // ---- Check new configuration
-    if (uiTechnicalDataSet[DEVICE_MODE_TEC]!=uiPreviousDeviceMode)
-    {      
-      UpdateSettings();
-      enPreviousMode=NUMBER_OF_MODE;                // Force full init of the variables
-      InitVentilation();  
-      uiPreviousDeviceMode=uiTechnicalDataSet[DEVICE_MODE_TEC];
-    }
-    
-    
-    switch(uiTechnicalDataSet[DEVICE_MODE_TEC])
-    {
-      default:
-      case VENTILATION_MODE:
-      {      
-        if (enVentilationMode==PS_MODE)
-          ManagePACVVentilation(TRUE);
-        else if (enVentilationMode==APCV_MODE)
-          ManagePACVVentilation(FALSE);
-        else if (enVentilationMode==AVC_MODE)
-          ManageVolumetricVentilation();
-        else if (enVentilationMode==CPAP_MODE)
-          ManageCPAPVentilation();             
-        break;
-      }
-      case ONE_CST_PWM_MODE:
-      {      
-        ManageOneCstPWM();             
-        break;
-      }
-      case TWO_CST_PWM_MODE:
-      {      
-        Manage2CstPWM();             
-        break;
-      }
-      case CST_SPEED_MODE:
-      {      
-        ManageCstSpeed();
-        break;
-      }
-      case FLOW_CAL_MODE:
-      {      
-        ManageFlowCalibration();
-        break;
-      }
-      case PRESSURE_CAL_MODE:
-      {      
-        ManagePressureCalibration();
-        break;
-      }
-      case PRESSURE_CST_MODE:
-      {
-        ManageCstPressure();
-        break;
-      }
-    }
-  }
-}
-
-
-/*******************************************************************************
-* Function Name  : StartStopVentilation
-* Description    : Detect a start/stop ventilation request
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void StartStopVentilation(void)
-{
-  #ifndef TEMPERATURE_TRENDS
-  opstatus_t  byOpStatus;  
-  #endif
-      
-  // Check if an alarm must stop the ventilation
-  ucStopVentilationAlarmNumber=ReadStopVentilationAlarmNumber();
-  
-  #ifndef TEMPERATURE_TRENDS  
-  if (uiTechnicalDataSet[START_STOP_VENTILATION]==1 && ucStopVentilationAlarmNumber==SIZE_BLOWER_ALARM)
-  {
-    // *************** VENTILATION is ON **************           
-    if (bMemoStartVentilation==FALSE)
-    {           
-      switch(ucStartVentilationScheduler)
-      {
-        default:
-        case 0:
-        {
-          // Active the HW safety system
-          ControlHW(BLOWER_ON__PAT_CPLD);
-          ucStartVentilationScheduler++;
-          break;
-        }
-        case 1:
-        {
-          // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
-          ControlHW(BLOWER_ON__PAT_CPLD);
-          
-          // Read Offset of the Blower current 
-          ComputeADCBlowerCurrent(TRUE);       
-          
-          ucStartVentilationScheduler++;
-          break;
-        }
-        case 2:
-        {
-          // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
-          ControlHW(BLOWER_ON__PAT_CPLD);
-          
-          // Open motor driver  
-          byOpStatus=SS_Xopen(mdrv);
-          if (byOpStatus==OPSTATUS_FAIL) 
-          {
-            uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_FAILURE_ALARM_MASK;      
-            ucStartVentilationScheduler=0;
-          }
-          else if (byOpStatus==OPSTATUS_OK)
-          {
-            // Force init settings and variables
-            uiPreviousDeviceMode=0xFF;  
-                    
-            uiTempo1min=TEMPO_1MIN;
-            #ifdef  DATA_LOGGING
-              uiTrendsSampleTime=RECORD_TRENDS_SAMPLE_TIME;
-            #endif  // DATA_LOGGING
-            
-            // Check if ventilation mode is activated
-            if (uiTechnicalDataSet[DEVICE_MODE_TEC]!=VENTILATION_MODE)
-              uiFlagsAlarm[ALARM_FLAGS2]|=DEVICE_MODE_ALARM_MASK;
-      
-            bMemoStartVentilation=TRUE;
-            ucStartVentilationScheduler=0;
-          }
-          break;
-        }
-      }
-    }                              
-    // --- Check Safety system for Motor transistors ----
-    else if (IsMotorOK()==FALSE)
-    {
-      ControlHW(BLOWER_OFF__STOP_PAT_CPLD); 
-      uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_FAILURE_ALARM_MASK;
-    }    
-    // --- Test safety system thanks to the "STOP_BLOWER" Input pin
-    else if (TestStopBlowerInputPin()==OPSTATUS_OK)  
-    {
-      ControlHW(BLOWER_ON__PAT_CPLD); 
-      uiFlagsAlarm[ALARM_FLAGS2]&=(~HW_SAFETY_ALARM_MASK);
-    }
-    else        
-    {
-      uiFlagsAlarm[ALARM_FLAGS2]|=HW_SAFETY_ALARM_MASK;                
-    }
-  }
-  else
-  #endif  // #ifndef TEMPERATURE_TRENDS  
-  {
-    // *************** VENTILATION is OFF **************
-    uiFlagsAlarm[ALARM_FLAGS2]&=(~DEVICE_MODE_ALARM_MASK); 
-    
-    if (ucStopVentilationAlarmNumber!=SIZE_BLOWER_ALARM)
-    {
-      // Stop patting CPLD (WDI_CPLD=0), STOP_BLOWER=0
-      ControlHW(BLOWER_OFF__STOP_PAT_CPLD);             
-    }
-    else 
-    {
-      // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
-      ControlHW(BLOWER_ON__PAT_CPLD);
-        
-      // ---- Test STOP_ACTUATOR Input pin Status
-      if (TestStopBlowerInputPin()==OPSTATUS_FAIL)      
-        uiFlagsAlarm[ALARM_FLAGS2]|=HW_SAFETY_ALARM_MASK; 
-      else
-        uiFlagsAlarm[ALARM_FLAGS2]&=(~HW_SAFETY_ALARM_MASK);
-    }
-    
-    if (bMemoStartVentilation==TRUE)
-    {
-      StopAllActuators();        
-      ClearAllVentilationAlarms();
-      ClearAllMeasures();
-    } 
-    
-    uiTechnicalDataSet[START_STOP_VENTILATION]=0;   
-    bMemoStartVentilation=FALSE;
-    #ifndef TEMPERATURE_TRENDS
-    ucStartVentilationScheduler=0;  
-    #endif
-    bDisableMaroubraCommCommunication=FALSE;
-  }  
-}
-#endif    // #ifndef C_M3_DEVICETEST_TARGET 
-
-
-/*******************************************************************************
-* Function Name  : ComputeTe
-* Description    : Compute expiratory time
-* Input          : uiF  = Breath frequency (bpm) 
-                   uiTi =  Inspiratory time (ms)
-* Output         : Expiratory time (ms)
-* Return         : None
-*******************************************************************************/
-#ifndef C_M3_DEVICETEST_TARGET 
-u16 ComputeTe(u16 uiF, u16 uiTi)
-{
-  u16 uiTtot;
-  u16 uiTeTemp=TE_SET_MIN;
-  
-  if (uiF!=0)
-  {
-    // Compute Ttotal
-    uiTtot=60000/uiF;
-    if (uiTtot>uiTi)
-    {
-      uiTeTemp=uiTtot-uiTi;
-      if (uiTeTemp<TE_SET_MIN)
-        uiTeTemp=TE_SET_MIN;      
-    }
-  }
-  else
-  {
-    // F=0 => Te=2xTi
-    uiTeTemp=uiTi<<1;
-  }            
-  return(uiTeTemp);
-}
-
-
-/*******************************************************************************
-* Function Name  : UpdateSettings
-* Description    : Update the settings zone with the temporary settings zone
-* Input          : None
-* Output         : None
-* Return         : TRUE if the ventilation mode has changed
-*******************************************************************************/
-bool UpdateSettings(void)
-{
-  u8  ucIndex;
-  
-  // Take into account a modification of the PEEP
-  if (uiVentilationSet[PEEP_SET]!=uiVentilationSetTemp[PEEP_SET] || uiVentilationSet[PS_CPAP_SET]!=uiVentilationSetTemp[PS_CPAP_SET])
-    uiMemoPWMDuringDisconnection=0;
-  
-  // Transfert data from the setting temporary zone to the settings zone    
-  for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)      
-    uiVentilationSet[ucIndex]=uiVentilationSetTemp[ucIndex];  
-  
-  // Update barometric expiratory time  
-  uiTeBaroSet=ComputeTe(uiVentilationSet[BREATH_RATE_BARO_SET], uiVentilationSet[TI_BARO_SET]);  
-  
-  // Update volumetric expiratory time
-  uiTeVoluSet=ComputeTe(uiVentilationSet[BREATH_RATE_VOLU_SET], uiVentilationSet[TI_VOLU_SET]);
-  
-  // Update Tube configuration type
-  enTubeConfigType=enTubeConfigTypeTemp;
-  
-  // Update Patient type
-  uiPatientType=uiPatientTypeTemp;
-  
-  // Update Ventilation mode
-  if (enVentilationMode!=enVentilationModeTemp)
-  {
-    enVentilationMode=enVentilationModeTemp;
-    InitVentilation();      
-    return(TRUE);
-  }  
-  return(FALSE);
-}
-
-
-/*******************************************************************************
-* Function Name  : ApplyNewVentilationMode
-* Description    : Update settings and init variables if the ventilation mode has changed
-* Input          : None
-* Output         : None
-* Return         : TRUE if new ventilation mode is applied
-*******************************************************************************/
-bool ApplyNewVentilationMode(void)
-{
-  if (fUpdateTheSettings==TRUE)
-  {
-      fUpdateTheSettings=FALSE;
-      if (UpdateSettings()==TRUE)
-      {
-        InitVentilation();
-        return(TRUE);
-      }
-  }
-  return(FALSE);
-}
-
-
-/*******************************************************************************
-* Function Name  : ComputeInspiratoryFlowSetPointInAVC
-* Description    : Compute:
-                      - the inspiratory flow max set point
-                      - the inspiratory flow min set point
-                      - the flow step between the flow max and the flow min during Ti
-* Input          : uiTypeOfPatient = Adult or Pedia
-                   uiVtc        = set point in volume (ml)
-                   uiTi         = Ti set point (ms)
-                   uiFlowShape  = Flow shape (0 to 4)
-* Output         : uiMaxFlow    = the inspiratory flow max set point (cl/min => 100=1l/min)
-                   uiMinFlow    = the inspiratory flow min set point (cl/min => 100=1l/min)
-                   uiFlowStep   = the flow step between the flow max and the flow min during Ti (cl/min => 100=1l/min)
-* Return         : None
-*******************************************************************************/
-void ComputeInspiratoryFlowSetPointInAVC(u16 uiTypeOfPatient, u16 uiVtc, u16 uiTi, u16 uiFlowShape, u32 *ulMaxFlow, u32 *ulMinFlow, u32 *ulFlowStep)
-{
-  u32	  ulFlowMax;
-  u32	  ulFlowMin;
-  u32     ulMaxMaxFlow;
-  u32     ulMinMinFlow;
-  u16     uiTiMin;
-  u32     ulFlowStepTemp;
-  
-  // Define min/max flow
-  if (uiTypeOfPatient==PATIENT_ADULT)
-  {
-    ulMinMinFlow=InspiratoryFlowSet_A_MIN;
-    ulMaxMaxFlow=InspiratoryFlowSet_A_MAX;
-    uiTiMin=TiVoluSet_A_MIN;
-  }
-  else
-  {
-    ulMinMinFlow=InspiratoryFlowSet_P_MIN;
-    ulMaxMaxFlow=InspiratoryFlowSet_P_MAX;
-    uiTiMin=TiVoluSet_P_MIN;
-  }
-  
-  // Check Ti
-  if (uiTi==0)
-    uiTi=uiTiMin;
-  
-  // Compute flow max
-  switch(uiFlowShape)
-  {
-    default:
-    case 0:
-    {
-      ulFlowMax=((u32)uiVtc*6000)/uiTi;
-      break;
-    }
-    case 1:
-    {
-      ulFlowMax=((u32)uiVtc*7500)/uiTi;
-      break;
-    }
-    case 2:
-    {
-      ulFlowMax=((u32)uiVtc*9000)/uiTi;
-      break;
-    }
-    case 3:
-    {
-      ulFlowMax=((u32)uiVtc*10500)/uiTi;
-      break;
-    }
-    case 4:
-    {
-      ulFlowMax=((u32)uiVtc*12000)/uiTi;
-      break;
-    }
-  }
-  
-  // Limitation of the max flow
-  if (ulFlowMax>ulMaxMaxFlow)
-    ulFlowMax=ulMaxMaxFlow;
-  
-  // Limitation of the min flow
-  if (ulFlowMax<ulMinMinFlow)
-    ulFlowMax=ulMinMinFlow;
-    
-  // Factor 100 on flow max (and flow min and flow step)  
-  ulFlowMax*=100;
-  
-  // Compute flow min and flow step
-  switch(uiFlowShape)
-  {
-    default:
-    case 0:
-    {
-      ulFlowMin=ulFlowMax;
-      break;
-    }
-    case 1:
-    {
-      ulFlowMin=(ulFlowMax*3)>>2;
-      break;
-    }
-    case 2:
-    {
-      ulFlowMin=ulFlowMax>>1;
-      break;
-    }
-    case 3:
-    {
-      ulFlowMin=ulFlowMax>>2;
-      break;
-    }
-    case 4:
-    {
-      ulFlowMin=0;
-      break;
-    }
-  }
-        
-  // Max flow
-  *ulMaxFlow=ulFlowMax;
-  
-  // Min flow
-  *ulMinFlow=ulFlowMin;
-  
-  // Flow Step  
-  ulFlowStepTemp=(ulFlowMax-ulFlowMin)/uiTi;
-  //if (uiFlowStepTemp==0 && uiFlowShape!=0) uiFlowStepTemp=1;
-  *ulFlowStep=ulFlowStepTemp;
-}
-
-
-
-/*******************************************************************************
-* Function Name  : TestTriggerExpiratoire
-* Description    : Manage the expiratory trigger
-* Input          : ucValeurSeuil = threshold (% of the flow max) to reach in order to cycle
-* Output         : None
-* Return         : TRUE if cycling active
-*******************************************************************************/
-unsigned char TestTriggerExpiratoire(unsigned char ucValeurSeuil, unsigned int uiPressureSetting)
-{
-  unsigned char  ucSeuil=ucValeurSeuil;
-  unsigned int   uiCalculTemp;
-  int16_t iConductanceBaseLine=UpdateInspiratoryConductanceAverage();
-  // Management automatic expiratory trigger
-  ucTempoTriggerExpiAuto--;
-  if (ucTempoTriggerExpiAuto==0)
-  {
-    ucTempoTriggerExpiAuto=TEMPO_TRIGGER_EXPI;
-    ucExpiTriggerTreshold++;
-  }
-  
-  // Test si flow<0??
-  if (iBlowerFlowSmoothingMes<0)
-  {
-    return(TRUE);  
-  }
-  // Test if deacring flow??
-  else if (iBlowerFlowSmoothingMes<iBlowerFlowSmoothingMaxMes)
-  {
-    // Test if Trigger Expi=AUTO ??
-    if ((ucValeurSeuil==ExpiTriggerSet_A_MAX && uiPatientType==PATIENT_ADULT) ||
-        (ucValeurSeuil==ExpiTriggerSet_P_MAX && uiPatientType==PATIENT_PEDIA))
-      ucSeuil=ucExpiTriggerTreshold;
-     
-    u16 conducThresh = 2000;
-    
-    if(enTubeConfigType == 1 )
-      conducThresh = 750;
-    else if(enTubeConfigType == 2)
-      conducThresh = 1500;
-      
-    // Test if cycling or not
-    uiCalculTemp=((unsigned long)iBlowerFlowSmoothingMaxMes*ucSeuil)/100;
-    if (uiCalculTemp>iBlowerFlowSmoothingMes)
-      return(TRUE);  
-    else if (uiProximalPressureMes>(uiPressureSetting+20))
-      return(TRUE);
-    else if (uiConductanceCalc < (iConductanceBaseLine - conducThresh))
-    {
-      ResetInspiratoryConductanceAverage();
-      return(TRUE); 
-    }
-  }
-  return(FALSE);
-}
-
-
-/*******************************************************************************
-* Function Name  : TestInspiratoryTrigger
-* Description    : Manage the inspiratory trigger
-* Input          : bSpont = TRUE if spontaneous mode
-*                  uiTe = expiration time (ms)
-*                  uiFlowTreshold = flow threshold (dl/min)
-* Output         : None
-* Return         : TRUE if cycling active
-*******************************************************************************/
-bool  TestInspiratoryTrigger(bool bSpont, u16 uiTe, u16 uiFlowTreshold)
-{  
-  //int16_t   iInspiratoryFlowDeltaAverage;
-  //int16_t   iDeltaOfTheDelta1, iDeltaOfTheDelta2, iDeltaOfTheDelta3, iDeltaOfTheDelta4;  
-  bool      bTrigger=FALSE;
-  //int16_t   iVirtualFlow;
-  int16_t   iConductanceBaseLine;
-  
-  // Manual breath management
-  if (uiTe>TE_SET_MIN)
-  {
-    if (bManualBreath==TRUE)
-    {
-      bManualBreath=FALSE;
-      bDisplayInspiratoryTrigger=TRUE;
-      return(TRUE);
-    }    
-  }
-  
-  // Trigger management
-  if ((bSpont==TRUE) || 
-      (bSpont==FALSE && uiFlowTreshold<InspiTriggerFlowSet_A_MAX && uiPatientType==PATIENT_ADULT) ||
-      (bSpont==FALSE && uiFlowTreshold<InspiTriggerFlowSet_P_MAX && uiPatientType==PATIENT_PEDIA))        
-  {
-    // Init scheduler
-    if (uiTe==1)
-    {
-      ucInspiTriggerScheduler=0;
-      iInspiratoryFlowMin=0;
-      ucMinFlowCounter=NUMBER_MIN_FLOW_VALUE;
-      ucCounterTriggerValid=NUMBER_TRIGGER_VALID;
-      bDetectionConstantFlow=FALSE;
-    }
-    
-    iConductanceBaseLine=UpdateInspiratoryConductanceAverage();
-    // Manage detection phase
-    switch(ucInspiTriggerScheduler)
-    {
-      default:
-      case 0:
-      {    
-        // Update the buffer on the Inspiratory flow average
-        
-        // Detect min flow
-        if (iBlowerFlowSmoothingMesForTrigger<iInspiratoryFlowMin)
-        {
-          iInspiratoryFlowMin=iBlowerFlowSmoothingMesForTrigger;
-          ucMinFlowCounter=NUMBER_MIN_FLOW_VALUE;
-        }
-        else
-        {
-          ucMinFlowCounter--;
-          if (ucMinFlowCounter==0)
-            ucInspiTriggerScheduler=1;
-        }        
-        break;
-      }            
-      case 1:
-      {    
-        //ucTriggerNumber=0;
-               
-        if (uiTe>TE_SET_MIN)
-        {
-//          // Fast trigger management
-//          if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50]<=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-25])
-//          {
-//            iVirtualFlow=(iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-25]<<1)-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50];                  
-//            if (iBlowerFlowSmoothingMesForTrigger>=(iVirtualFlow+(int16_t)(uiFlowTreshold*7)))
-//            {
-//              //ucTriggerNumber=1;
-//              //if (fBlockCloseLoop==FALSE)
-//                bTrigger=TRUE;    
-//            }
-//          }          
-//          if (bTrigger==FALSE && iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-100]<=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50])
-//          {
-//            iVirtualFlow=(iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50]<<1)-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-100];
-//            if (iBlowerFlowSmoothingMesForTrigger>=(iVirtualFlow+(int16_t)(uiFlowTreshold*15)))
-//            {
-//              //ucTriggerNumber=2;
-//              //if (fBlockCloseLoop==FALSE)
-//                bTrigger=TRUE;            
-//            }
-//          }
-//                    
-//          // Slow trigger management
-//          if (TestInspiratorySlowTrigger(iFlowBaseLine, uiFlowTreshold*10)==TRUE)
-//          {
-//            //ucTriggerNumber=3;
-//            bTrigger=TRUE;
-//          }                    
-             //Conductance Trigger
-          if(uiConductanceCalc >= (iConductanceBaseLine + 2000))
-          {
-            bTrigger = TRUE;            
-          }
-        
-          // Trigger occurs??
-          if (bTrigger==TRUE)
-          {
-            ucCounterTriggerValid--;
-            if (ucCounterTriggerValid==0) 
-            {
-              bDisplayInspiratoryTrigger=TRUE;
-              ResetInspiratoryConductanceAverage();
-              return(TRUE);            
-            }
-          }        
-          else          
-            ucCounterTriggerValid=NUMBER_TRIGGER_VALID;          
-        }
-        break;
-      }
-    }
-  }
-  return(FALSE);
-}
-        
-/*******************************************************************************
-* Function Name  : UpdateInspiratoryConductanceAverage
-* Description    : Fill the buffer with the expiratory conductance and compute the average
-* Input          : None
-* Output         : None
-* Return         : Inspiratory flow average
-*******************************************************************************/        
-u16         conducIndex = 0;
-int32_t     lSumConductance = 0;
-bool bufFilled = FALSE;
-  
-int16_t UpdateInspiratoryConductanceAverage(void)
-{
-  int16_t oldValue = iBufferIFlow[conducIndex];
-  iBufferIFlow[conducIndex] = uiConductanceCalc;
-  lSumConductance += uiConductanceCalc;
-  conducIndex++;
-  
-  if(conducIndex > SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER)
-  {
-    conducIndex = 0;
-    bufFilled = TRUE;
-  }
-  
-  if(bufFilled)
-  {
-    lSumConductance -= oldValue;
-    return (lSumConductance/SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER); 
-  }
-  else
-  {
-    return (lSumConductance/conducIndex); 
-  }
-}
-
-/*******************************************************************************
-* Function Name  : ResetInspiratoryConductanceAverage
-* Description    : Fill the buffer with the expiratory conductance and compute the average
-* Input          : None
-* Output         : None
-* Return         : Inspiratory flow average
-*******************************************************************************/        
-  
-void ResetInspiratoryConductanceAverage(void)
-{
-  conducIndex = 0;
-  lSumConductance = 0;
-  bufFilled = FALSE;
-}
-
-/*******************************************************************************
-* Function Name  : UpdateInspiratoryFlowAverage
-* Description    : Fill the buffer with the inspiratory flow and compute the average
-* Input          : None
-* Output         : None
-* Return         : Inspiratory flow average
-*******************************************************************************/        
-int16_t UpdateInspiratoryFlowAverage(void)
-{
-  u16         uiIndex;
-  int32_t     lSumIFlow=0;
-  
-  // Roll the buffer
-  for(uiIndex=1; uiIndex<SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER; uiIndex++)
-  {
-    iBufferIFlow[uiIndex-1]=iBufferIFlow[uiIndex];                    // Upate the Inspiratory Flow buffer
-    lSumIFlow+=iBufferIFlow[uiIndex-1];                               // Sum the Inspiratory Flow
-  }
-    
-  // Add new flow value
-  iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]=iBlowerFlowSmoothingMesForTrigger;   // Upate the Inspiratory Flow buffer
-  lSumIFlow+=iBlowerFlowSmoothingMesForTrigger;                                           // Sum the Inspiratory Flow     
-  
-  return(lSumIFlow/SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER); 
-}        
-
-
-/*******************************************************************************
-* Function Name  : TestInspiratorySlowTrigger
-* Description    : Compute flow base line and test trigger
-* Input          : FlowTreshold = flow threshold (cl/min)
-* Output         : None
-* Return         : TRUE if trigger occurs
-*******************************************************************************/        
-bool TestInspiratorySlowTrigger(int16_t iTheFlowBaseLine, u16 uiFlowTreshold)
-{
-  int16_t   iFlowDelta1, iFlowDelta2, iFlowDelta3;
-  
-  if (bDetectionConstantFlow==FALSE)
-  {
-    // Detection constant flow
-    if (iBufferIFlow[0]<iTheFlowBaseLine)
-      iFlowDelta1=iTheFlowBaseLine-iBufferIFlow[0];
-    else
-      iFlowDelta1=iBufferIFlow[0]-iTheFlowBaseLine;
-    
-    if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1]<iTheFlowBaseLine)
-      iFlowDelta2=iTheFlowBaseLine-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1];
-    else
-      iFlowDelta2=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1]-iTheFlowBaseLine;
-    
-    if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]<iTheFlowBaseLine)
-      iFlowDelta3=iTheFlowBaseLine-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1];
-    else
-      iFlowDelta3=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]-iTheFlowBaseLine;
-    
-    if (iFlowDelta1<60 && iFlowDelta2<60 && iFlowDelta3<60)
-    {
-      iFlowBaseLineReference=iTheFlowBaseLine;
-      bDetectionConstantFlow=TRUE;
-    }
-  }
-  else
-  {
-    // Detect trigger
-    if (iBlowerFlowSmoothingMesForTrigger>=(iFlowBaseLineReference+(int16_t)uiFlowTreshold))
-    {
-      return(TRUE);
-    }
-  }
-  return(FALSE);
-}
-
-
-/*******************************************************************************
-* Function Name  : ApplyDefaultValueToTemporaryVentilationSettings
-* Description    : Init temporary ventilation settings with default values
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/        
-void ApplyDefaultValueToTemporaryVentilationSettings(void)
-{
-  u8  ucIndex;
-  
-  enVentilationModeTemp=VentilationMode_DEF;          
-  uiPatientTypeTemp=PatientType_DEF; 
-  enTubeConfigTypeTemp=(enMaroubraTubeConfigurationList)ReturnDefaultTubeConfiguration(VentilationMode_DEF);
-  
-  // Init all temporary settings
-  if (uiPatientType==PATIENT_ADULT)
-  {
-    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
-      uiVentilationSetTemp[ucIndex]=sLRSGroup[ucIndex].uiDefault_Adult;
-  }
-  else
-  {
-    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
-      uiVentilationSetTemp[ucIndex]=sLRSGroup[ucIndex].uiDefault_Pedia;
-  }
-}
-
-
-/*******************************************************************************
-* Function Name  : CheckTemporaryVentilationSettingRange
-* Description    : Check all the temporary settings range
-* Input          : None
-* Output         : None
-* Return         : FALSE if one the settings is out of range
-*******************************************************************************/
-opstatus_t CheckTemporaryVentilationSettingRange(void)
-{
-  u8  ucIndex;
-  
-  if ((uiPatientTypeTemp==PATIENT_PEDIA || uiPatientTypeTemp==PATIENT_ADULT) && enVentilationModeTemp<NUMBER_OF_MODE && enTubeConfigTypeTemp<NUMBER_OF_TUBE_CONFIGURATION)
-  {   
-    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
-    {
-      // Check data range
-      if (uiPatientTypeTemp==PATIENT_PEDIA)
-      {
-        if (uiVentilationSetTemp[ucIndex]<sLRSGroup[ucIndex].uiMin_Pedia)
-          return(OPSTATUS_FAIL);
-        else if (uiVentilationSetTemp[ucIndex]>sLRSGroup[ucIndex].uiMax_Pedia)
-          return(OPSTATUS_FAIL);
-      }
-      else
-      {
-        if (uiVentilationSetTemp[ucIndex]<sLRSGroup[ucIndex].uiMin_Adult)
-          return(OPSTATUS_FAIL);
-        else if (uiVentilationSetTemp[ucIndex]>sLRSGroup[ucIndex].uiMax_Adult)
-          return(OPSTATUS_FAIL);
-      }
-    }
-    return(OPSTATUS_OK);
-  }
-  return(OPSTATUS_FAIL);
-}
-
-
-
-/*******************************************************************************
-* Function Name  : ApplyDefaultValueToTechnicalSettings
-* Description    : Init technical settings with default values
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/        
-void ApplyDefaultValueToTechnicalSettings(void)
-{
-  u8  ucIndex;
-  
-  // Init all temporary settings
-  for (ucIndex=0; ucIndex<SIZE_LRTS_GROUP; ucIndex++)
-    uiTechnicalDataSet[ucIndex]=sLRTSGroup[ucIndex].uiDefault;
-}
-
-
-/*******************************************************************************
-* Function Name  : CheckTechnicalSettingsRange
-* Description    : Check all the technical settings range
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void CheckTechnicalSettingsRange(void)
-{
-  u8    ucIndex;
-  bool  fError=FALSE;
-  
-  for (ucIndex=0; ucIndex<SIZE_LRTS_GROUP; ucIndex++)
-  {
-    if (uiTechnicalDataSet[ucIndex]<sLRTSGroup[ucIndex].uiMin || uiTechnicalDataSet[ucIndex]>sLRTSGroup[ucIndex].uiMax)
-    {
-      uiTechnicalDataSet[ucIndex]=sLRTSGroup[ucIndex].uiDefault;
-      fError=TRUE;
-      //break;
-    }
-  }
-  
-  if (fError==TRUE)
-    uiFlagsAlarm[ALARM_FLAGS2]|=TECHNICAL_SETTINGS_RANGE_ALARM_MASK;
-  else
-    uiFlagsAlarm[ALARM_FLAGS2]&=(~TECHNICAL_SETTINGS_RANGE_ALARM_MASK);
-}
-
-
-/*******************************************************************************
-* Function Name  : CheckFlowLUTRange
-* Description    : Check the flow LUT
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void CheckFlowLUTRange(void)
-{
-  u16   uiIndex;
-  bool  fError=FALSE;
-  
-  if (stLUTFlowSensor.uiLUT_TableSize<(FLOW_CALIB_NUMBER_OF_SAMPLES>>1) || stLUTFlowSensor.uiLUT_TableSize>FLOW_CALIB_NUMBER_OF_SAMPLES)
-  {
-    ApplyDefaultFlowLUT();
-    fError=TRUE;
-  }
-  else
-  {
-    for (uiIndex=1; uiIndex<stLUTFlowSensor.uiLUT_TableSize; uiIndex++)
-    {
-      if (stLUTFlowSensor.uiFlowValue[uiIndex]<=stLUTFlowSensor.uiFlowValue[uiIndex-1]  || 
-          stLUTFlowSensor.uiFlowSensorTicks[uiIndex]<=stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1])
-      {
-        ApplyDefaultFlowLUT();
-        fError=TRUE;
-        break;
-      }
-    }
-  }
-  
-  if (fError==TRUE)
-    uiFlagsAlarm[ALARM_FLAGS2]|=NO_FLOW_LUT_ALARM_MASK;
-  else
-    uiFlagsAlarm[ALARM_FLAGS2]&=(~NO_FLOW_LUT_ALARM_MASK);
-}
-
-
-/*******************************************************************************
-* Function Name  : ApplyDefaultFlowLUT
-* Description    : Apply default value for the flow LUT
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ApplyDefaultFlowLUT(void)
-{
-  u16   uiIndex;
-  
-  stLUTFlowSensor.uiLUT_TableSize=stDefaultLUTFlowSensor.uiLUT_TableSize;
-  for (uiIndex=0; uiIndex<FLOW_CALIB_NUMBER_OF_SAMPLES; uiIndex++)
-  {
-    stLUTFlowSensor.uiFlowValue[uiIndex]=stDefaultLUTFlowSensor.uiFlowValue[uiIndex];
-    stLUTFlowSensor.uiFlowSensorTicks[uiIndex]=stDefaultLUTFlowSensor.uiFlowSensorTicks[uiIndex];
-  }
-}
-
-
-/*******************************************************************************
-* Function Name  : ReturnDefaultTubeConfiguration
-* Description    : The default tubing configuration according to the current ventilation mode
-* Input          : a ventilation mode
-* Output         : None
-* Return         : The tube configuration
-*******************************************************************************/
-u16 ReturnDefaultTubeConfiguration(u16 uiMode)
-{
-  u8  ucIndex;
-  
-  for (ucIndex=0; ucIndex<NUMBER_OF_TUBE_CONFIGURATION; ucIndex++)
-  {
-    if (ucTubeConfigurationTable[ucIndex][uiMode]==TUBE_DEFAULT)
-    {
-      return(ucIndex);
-    }
-  }
-  return(0);
-}
-
-
-/*******************************************************************************
-* Function Name  : ApplyAllDefaultValues
-* Description    : Apply all default values in the technical and settings zones
-*                : BE CARFUL this function call "ControlHW" function
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void ApplyAllDefaultValues(void)
-{ 
-  // Init ventilation settings
-  ApplyDefaultValueToTemporaryVentilationSettings();
-    
-  // Init technical settings
-  ApplyDefaultValueToTechnicalSettings();
-  
-  // Init flow LUT
-  ApplyDefaultFlowLUT();
-  
-  // Default value for the device/patient time counter
-  ulDeviceTimeCounter=0;
-  ulPatientTimeCounter=0;
-        
-  // Default value for the blower revolution counter
-  ulBlowerRevolutionCounter=0;
-  
-  bComputeOffsetSensors=TRUE;
-}
-#endif  // C_M3_DEVICETEST_TARGET 
-
-/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ventilation.txt	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,3355 @@
+
+/* Includes ------------------------------------------------------------------*/
+#define EXTERN extern
+#include <stdlib.h>                   
+#include <string.h>                   
+#include "SS.h"                   
+#include "main.h"
+#include "_SS_OnOffActioner.h"
+#include "_SS_Pwm.h"
+#include "Monitoring.h"
+#include "Safety.h"
+#include "_SS_Data_Logging.h"
+#include "_SS_Record_Settings.h"
+#include "_SS_I2CX_SDP600.h"
+#include "_SS_I2CX_X201641.h"
+#include "_SS_OptimaComm.h"
+#undef EXTERN
+
+#define INIT_VARIABLES
+#define EXTERN 
+#include "Ventilation.h"   
+#undef  EXTERN
+#undef  INIT_VARIABLES
+
+
+/* Internal constants --------------------------------------------------------*/
+// ******************* Min-max PI or PDF ***************************************
+#define       MAX_VOLTAGE_REF                           MAX_PI_OUTPUT  // MAX_PI_OUTPUT = 1343 = 18.5micros = 93.3%, want 80%
+#define       MIN_VOLTAGE_REF                           MIN_PI_OUTPUT
+#define       INTEGRAL_MAX                              (2147483647)
+#define       INTEGRAL_MIN                              (-2147483648)
+
+
+#ifndef C_M3_DEVICETEST_TARGET 
+  /* Internal variables --------------------------------------------------------*/
+  // ******************* MANAGED CONSTANT SPEED ****************************
+  static  u16           uiBlowerSpeedSetting;
+  static  int32_t       lIntegral_Speed_I;
+  static  bool          bMaxPIOutputSpeedI;
+  static  bool          bMinPIOutputSpeedI;
+    
+    
+  // ************* MANAGED BAROMETRIC VENTILATION *************************  
+  static  u16           uiIpapSettingTemp;
+  static  u16           uiTeBaroSet;
+  static  int32_t       lIntegral_Pressure_I;
+  static  bool          bMaxPIOutputPressureI;
+  static  bool          bMinPIOutputPressureI; 
+  static  u16           uiTiD;
+  static  u8            ucIndexTableSlope;
+  #define   TEMPO_TRIGGER_EXPI                30
+  static  u8            ucTempoTriggerExpiAuto;
+  #define   MIN_THRESHOLD_EXPI_TRIGGER_AUTO   25
+  static  u8            ucExpiTriggerTreshold;
+  static  u8            fFirstCycleInspi;
+     
+  // ----------- Main blower management during expiration -------------------  
+  static  u16           uiPWMatTheEndOfInspiration;
+  static  bool          fFirstCycleExpi;      
+  static  u16           uiEpapSettingTemp;
+  static  int32_t       lIntegral_Pressure_E;
+  static  bool          bMaxPIOutputPressureE;
+  static  bool          bMinPIOutputPressureE;     
+  static  u16           uiPWMatTheEndOfExpiration;  
+  static  u16           uiTeD;  
+  static  bool          fBlockCloseLoop;
+  
+  static  u16           uiTiTyp;  
+    
+  // ************* MANAGED VOLUMETRIC VENTILATION *************************  
+  static  u32           ulMaxIFlowSet;
+  static  u32           ulMinIFlowSet;
+  static  u32           ulDecFlowStep;
+  static  u16           uiTeVoluSet;
+  static  u16           uiProximalPressureAtTheEndOfInspiration;
+  static  int32_t       lIntegral_Flow_I;
+  static  bool          bMaxPIOutputFlowI;
+  static  bool          bMinPIOutputFlowI;    
+  static  int16_t       iVtAdjust=0;
+  static  u8            ucCounterHPAlarm=0;    
+    
+    
+  // ******************* MANAGED_CPAP_VENTILATION ******************************  
+  #define EXPIRATORY_DISCONNECTION_TIME_OUT         500   // 500ms
+  #define CPAP_DISCONNECTION_TEST_PERIODICITY       4000  // 4s
+  static  u16           uiDisconnectionTime;  
+  static  u16           uiDisconnectionTimeInCPAP;    
+  static  u16           uiMemoPWMDuringDisconnection;
+  //static  u8            ucStandByMode;
+  
+  // ***************** MANAGED INSPIRATORY TRIGGER *****************************
+  #define MAX_DELTA_FLOW                            100   // 1 l/min
+  #define SIZE_DELTA_INSPIRATORY_FLOW_BUFFER        40
+  #define NUMBER_TRIGGER_VALID                      20
+  #define NUMBER_MIN_FLOW_VALUE                     30
+  //static  int16_t       iBufferIFlowDelta[SIZE_DELTA_INSPIRATORY_FLOW_BUFFER];  
+  static  u8            ucInspiTriggerScheduler;
+  static  u8            ucMinFlowCounter;
+  static  int16_t       iInspiratoryFlowMin;
+  //static  int16_t       iOldInspiratoryFlowSmoothingMesForTrigger;
+  #define SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER      250
+  static  int16_t       iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER];
+ // static  int16_t       iBufferConductance[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER];
+  static  u8            ucCounterTriggerValid;
+  static  int16_t       iFlowBaseLineReference;
+  static  bool          bDetectionConstantFlow;  
+
+  
+  // *********************** MANAGED MONITORING FOR MLT ************************
+  static  u16           uiMLT_PressureSetPoint;
+  #ifdef MOTOR_LIFE_TESTING
+    #define MLT_AVERAGE_MONITORING                 1000
+    static  u16           uiAverageMonitoringMLT;    
+    static  u32           ulMLT_SumSpeedMes;
+    static  u32           ulMLT_SumCurrentMes;
+    static  u32           ulMLT_SumTemperatureMes;
+    static  u32           ulMLT_SumBlowerVoltage;
+    static  u16           uiMLT_EnableAlarm;    
+  #endif  // #ifdef MOTOR_LIFE_TESTING
+      
+  
+  // ************************ MANAGED CALIBRATION ******************************
+  typedef enum
+  {
+    INIT_FLOW_CALIB_TEST=0,
+    SET_GAS_TYPE,
+    SET_GAS_STANDARD,
+    START_FLOW_READING,
+    SEND_FLOW_COMMAND,
+    READ_FLOW_VALUE,        
+    SEND_HIGH_FLOW_CALIB_REQUEST,    
+    WAIT_FOR_HIGH_FLOW_CALIB_ACK,
+    PREPARE_FAILURE_COMMAND,
+    PREPARE_SUCCESS_COMMAND,
+    SEND_COMMAND_TO_PF300,
+    CHECK_COMMAND_FROM_PF300,
+    END_OF_CALIBRATION,
+  } type_enLowFlowCalibrationStep;
+
+  typedef enum
+  {
+    INIT_PRESSURE_CALIB_TEST=0,
+    START_PRESSURE_READING,    
+    SEND_PRESSURE_COMMAND,    
+    READ_PRESSURE_VALUE,  
+    PRESSURE_CALIB_FAILURE_COMMAND,
+    PRESSURE_CALIB_SUCCESS_COMMAND,
+    PRESSURE_CALIB_SEND_COMMAND_TO_PF300,
+    PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300,
+    PRESSURE_CALIB_END_OF_CALIBRATION,
+  } type_enPressureCalibrationStep;
+  
+  #define SIZE_BUFFER_FLOW_VALUE                    15
+  typedef struct
+  {
+    unsigned char   ucIndex;
+    bool            bFirstPartOfTheCRReceived;
+    char            szValue[SIZE_BUFFER_FLOW_VALUE];
+  } type_stFlow;
+  
+  // Flow and pressure calibration  
+  #define TIME_OUT_RECEPTION_PACKET_FROM_PF300      2000  // 2s
+  #define SAMPLE_RATE_BETWEEN_TWO_FLOW              5000  // 5s  
+  #define SIZE_RX_BUFFER_PF300                      20  
+  static  u16                                     uiCalibrationTimeOut;
+  static  unsigned char                           ucIndexAnswerFromPF300;
+  static  char                                    szAnswerFromPF300[SIZE_RX_BUFFER_PF300];
+  static  char                                    szExpectedAnswerFromPF300[SIZE_RX_BUFFER_PF300];
+  static  u8                                      ucNumberOfBytesToCheckFromPF300Answer;    
+  
+  // Flow calibration
+  static  type_enLowFlowCalibrationStep           enLowFlowCalibrationStep;
+  static  type_enLowFlowCalibrationStep           enGoBackToStep;
+  static  unsigned long                           ulSumFlowTicks;
+  static  unsigned int                            uiFlowTicksSamplesCounter;
+  //static  type_stLUTFlowSensor                    stTemporayLUTFlowSensor;  
+  static  bool                                    bHighFlowCalibrationInProgress;    
+  static  unsigned int                            uiMotorDutyCyleForFlowCalib;
+  static  unsigned int                            uiImHereMsgTimer;
+  
+  // Pressure calibration
+  #define SAMPLE_RATE_BETWEEN_TWO_PRESSURE          10000  // 30s             
+  static  type_enPressureCalibrationStep          enPressureCalibrationStep;
+  static  type_enPressureCalibrationStep          enPressureCalibGoBackToStep;
+  static  u32                                     ulSumPressureTicks;
+  static  u16                                     uiPressureTicksSamplesCounter;
+  
+  // List of command to PF300
+  static  const char                              szPF300_CmdSwitchOffEcho[]={"%CM#5$0\r"};    // Command Echo from PF300 off
+  static  const char                              szPF300_AnswerSwitchOffEcho[]={"%CM#5"};     // Answer echo off from PF300 (WO \r)
+  static  const char                              szPF300_SetAirGasType[]={"%WS#1$0\r"};       // command Air  
+  static  const char                              szPF300_AnswerAirGasType[]={"%WS#1$0"};      // Answer Air  
+  static  const char                              szPF300_SetGasStandard[]={"%WS#3$1\r"};      // Command STPD
+  static  const char                              szPF300_AnswerGasStandard[]={"%WS#3$1"};     // Answer STPD  
+  static  const char                              szPF300_ReadLowFlowCmd[]={"%RM#1\r"};        // Command read low flow
+  static  const char                              szPF300_ReadLowFlowAnswer[]={"%RM#1$"};      // Answer read low flow
+  static  const char                              szPF300_ReadHighFlowCmd[]={"%RM#0\r"};       // Command read high flow
+  static  const char                              szPF300_ReadHighFlowAnswer[]={"%RM#0$"};     // Answer read high flow 
+  static  const char                              szPF300_ReadPdiffCmd[]={"%RM#3\r"};          // Command read pressure diff.
+  static  const char                              szPF300_ReadPdiffAnswer[]={"%RM#3$"};        // Answewr read pressure diff.
+  
+  // List of Command to Handset
+  static  const char                              szRequestHighFlowCalib[]={"@N"};
+  static  const char                              szEndOfCalibOK[]={"@S"};  
+  static  const char                              szImHere[]={"@*"};
+    
+    
+  // ---------------- Management FRAM for settings -----------------------------
+  #ifdef RECORD_SETTINGS      
+  #endif    // RECORD_SETTINGS           
+  
+  // -------------------- Manage Motor starting --------------------------------
+  #ifndef TEMPERATURE_TRENDS
+  static  u8              ucStartVentilationScheduler=0;  
+  #endif
+  static  enMaroubraModes enPreviousMode;
+  static  u16             uiPreviousDeviceMode;
+#endif      // C_M3_DEVICETEST_TARGET
+  
+    
+#ifndef C_M3_DEVICETEST_TARGET   
+  #define SIZE_SLOPE2_TABLE   21
+  const unsigned char ucSlope2Table[SIZE_SLOPE2_TABLE]= {
+  0,  35, 50, 59, 65, 70, 74, 77, 80, 83,
+  85, 87, 89, 91, 92, 94, 95, 96, 98, 99,
+  100 };
+  
+  // Table pente inspiratoire 2
+  #define SIZE_SLOPE3_TABLE   41
+  const unsigned char ucSlope3Table[SIZE_SLOPE3_TABLE]= {
+  0,  20, 35, 44, 50, 55, 59, 62, 65, 68, 70,
+  72, 74, 76, 77, 79, 80, 81, 83, 84, 85, 86,
+  87, 88, 89, 90, 91, 91, 92, 93, 94, 94, 95,
+  96, 96, 97, 98, 98, 99, 99, 100 };
+  
+  // Table pente inspiratoire 3
+  #define SIZE_SLOPE4_TABLE   61
+  const unsigned char ucSlope4Table[SIZE_SLOPE4_TABLE]= {
+  0,  11, 26, 35, 41, 46, 50, 53, 56, 59, 61,
+  63, 65, 67, 68, 70, 71, 73, 74, 75, 76, 77,
+  78, 79, 80, 81, 82, 83, 83, 84, 85, 86, 86,
+  87, 88, 88, 89 ,90, 90, 91, 91, 92, 92, 93,
+  93, 94, 94, 95, 95, 96, 96, 96, 97, 97, 98,
+  98, 99, 99, 99, 100, 100 };
+  
+  
+  // Maximum allowed flow in expiration Flow=f(PEEP set) (example: flow-by max=29L/min @ 5hPa)
+  const   u16           uiMaximumFlowInExpiration[41]={                    
+    0, 1300, 1830, 2250, 2600, 2900, 3180, 3430, 3670, 3900, 
+    4110, 4310, 4500, 4680, 4860, 5030, 5200, 5360, 5510, 5660,
+    5810, 5950, 6090, 6230, 6360, 6500, 6620, 6750, 6870, 7000,
+    7120, 7230, 7350, 7460, 7580, 7690, 7800, 7900, 8010, 8110, 8220
+  };  
+#endif  // C_M3_DEVICETEST_TARGET
+
+
+/* Internal functions --------------------------------------------------------*/
+#ifndef C_M3_DEVICETEST_TARGET   
+  u16           ComputeTe(u16 uiF, u16 uiTi);
+  void          ComputeInspiratoryFlowSetPointInAVC(u16 uiTypeOfPatient, u16 uiVtc, u16 uiTi, u16 uiFlowShape, u32 *ulMaxFlow, u32 *ulMinFlow, u32 *ulFlowStep);
+  unsigned char TestTriggerExpiratoire(unsigned char ucValeurSeuil, unsigned int uiPressureSetting);
+  bool          TestInspiratoryTrigger(bool bSpont, u16 uiTe, u16 uiFlowThreshold);
+  int16_t       UpdateInspiratoryFlowAverage(void);
+  int16_t       UpdateInspiratoryConductanceAverage(void);
+  void          ResetInspiratoryConductanceAverage(void);
+  bool          TestInspiratorySlowTrigger(int16_t iTheFlowBaseLine, u16 uiFlowTreshold);
+  void          ApplyDefaultValueToTemporaryVentilationSettings(void);  
+  void          ApplyDefaultValueToTechnicalSettings(void);
+  void          ApplyAllDefaultValues(void);
+  bool          ApplyNewVentilationMode(void);
+  void          ApplyDefaultFlowLUT(void);
+  void          CheckFlowLUTRange(void);
+  void          ManageFlowCalibration(void);
+  void          ManagePressureCalibration(void);
+  void          ManageCstPressure(void);
+#endif  // C_M3_DEVICETEST_TARGET
+
+  
+  
+#ifndef C_M3_DEVICETEST_TARGET 
+/*******************************************************************************
+* Function Name  : InitSettings
+* Description    : Initialize parameters for ventilation
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void InitSettings(void)
+{    
+  uiPreviousDeviceMode=0xFF;
+  enPreviousMode=NUMBER_OF_MODE;     
+            
+  // --- Init Settings
+  uiTechnicalDataMes[SW_VERSION_TEC_MES]=MAROUBRA_BLOWER_SW_VERSION;
+  bComputeOffsetSensors=FALSE;
+        
+  #ifdef RECORD_SETTINGS
+    // Read and init FRAM        
+    if (InitSettingsZoneAndTechnicalZoneInFRAM()==OPSTATUS_OK)
+    {      
+      if (ReadSettingsZoneAndTechnicalZoneInFRAM()==OPSTATUS_FAIL)
+      {
+        uiFlagsAlarm[ALARM_FLAGS2]|=FRAM_FAILURE_ALARM_MASK;
+        ApplyAllDefaultValues();
+      }
+    }  
+    else
+    {
+      uiFlagsAlarm[ALARM_FLAGS2]|=FRAM_FAILURE_ALARM_MASK;
+      ApplyAllDefaultValues();
+    }
+  #else  
+    ApplyAllDefaultValues();
+  #endif
+    
+  // Compute offsets sensors if necessary
+  if (bComputeOffsetSensors==TRUE)
+  {    
+    // ------ Update Blower Flow sensor offset before ventilation -------
+    #ifdef SDP600_USED_I2C1_BUS
+    SDP600_ComputeOffsetFlowSensorOnI2C1(SDP600_BLOWER_FLOW_SENSOR);      
+    #endif  // SDP600_USED_I2C1_BUS 
+    
+    #ifdef X201641_USED_I2C1_BUS
+    X201641_ComputeOffsetFlowSensorOnI2C1(X201641_BLOWER_FLOW_SENSOR);
+    #endif  // X201641_USED_I2C1_BUS                
+                
+    // ----- Update Proximal Pressure sensor offset before ventilation -------
+    ComputeOffsetProximalPressureSensor();             
+  }
+        
+  // Check Technical settings range
+  CheckTechnicalSettingsRange();
+  
+  // Check Flow LUT
+  CheckFlowLUTRange();
+  
+  // Check temporary ventilation setting range
+  if (CheckTemporaryVentilationSettingRange()==OPSTATUS_FAIL)
+  {
+    ApplyDefaultValueToTemporaryVentilationSettings();
+    uiFlagsAlarm[ALARM_FLAGS2]|=VENTILATION_SETTINGS_RANGE_ALARM_MASK;
+  }
+
+  // --- Update computed settings (Te,...)
+  UpdateSettings();
+  
+  #ifdef MOTOR_LIFE_TESTING
+    uiTechnicalDataSet[DEVICE_MODE_TEC]=PRESSURE_CST_MODE;
+    uiTechnicalDataSet[START_STOP_VENTILATION]=1;
+  #endif
+}
+
+
+/*******************************************************************************
+* Function Name  : InitVentilation
+* Description    : Initialize variables for ventilation
+*                  Function called :
+*                     - when we start ventilation
+*                     - when we change of ventilation mode
+*                     - when we change of device mode
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void InitVentilation(void)
+{ 
+  ucVentilationCycle=EXPIRATION_CYCLE;
+  uiTiD=0;  
+  uiTeD=0;
+  uiTiTyp = 1000;  
+  bManualBreath=FALSE;
+  
+  if (enPreviousMode==NUMBER_OF_MODE)
+  {
+    // Start ventilation
+    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;  
+    uiDisconnectionTimeInCPAP=CPAP_DISCONNECTION_TEST_PERIODICITY;  
+    uiMemoPWMDuringDisconnection=0;
+    fBlockCloseLoop=FALSE;     
+  }
+  
+  ClearAllVentilationAlarms();
+  ClearAllMeasures();
+  
+  switch(uiTechnicalDataSet[DEVICE_MODE_TEC])
+  {
+  default:
+  case VENTILATION_MODE:
+    {      
+      if (enVentilationMode==APCV_MODE || enVentilationMode==PS_MODE)
+      {
+        if (enPreviousMode==APCV_MODE || enPreviousMode==PS_MODE)
+        {
+          // --- We are already in pressure mode
+        }
+        else
+        {
+          // --- Start a pressure mode
+          fFirstCycleInspi=TRUE;
+          uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF; 
+          
+          if (enPreviousMode!=AVC_MODE)
+          {
+            uiPWMatTheEndOfExpiration=MIN_VOLTAGE_REF;
+            lIntegral_Pressure_E=0;
+            bMaxPIOutputPressureE=FALSE;
+            bMinPIOutputPressureE=FALSE;
+            fFirstCycleExpi=TRUE;   
+          }
+        }                        
+      }
+      else if (enVentilationMode==AVC_MODE)
+      {      
+        iVtAdjust=0;
+        fFirstCycleInspi=TRUE;
+        uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;
+        
+        if (enPreviousMode!=APCV_MODE && enPreviousMode!=PS_MODE)
+        {           
+          uiPWMatTheEndOfExpiration=MIN_VOLTAGE_REF;
+          lIntegral_Pressure_E=0;
+          bMaxPIOutputPressureE=FALSE;
+          bMinPIOutputPressureE=FALSE;
+          fFirstCycleExpi=TRUE;   
+        }
+      }
+      else if (enVentilationMode==CPAP_MODE)
+      {              
+        Ki_Pressure_I=1000;  
+        uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;   
+        lIntegral_Pressure_I=0;
+        bMaxPIOutputPressureI=FALSE;
+        bMinPIOutputPressureI=FALSE;        
+      }
+      break;
+    }  
+  case ONE_CST_PWM_MODE:
+    {       
+      uiInspirationBlowerPWMTec=250;
+      break;
+    }
+  case TWO_CST_PWM_MODE:
+    {      
+      uiInspirationBlowerPWMTec=350; 
+      uiExpirationBlowerPWMTec=150;
+      break;
+    }
+  case CST_SPEED_MODE:
+    {           
+      uiBlowerSpeedSet=15000;
+      uiBlowerSpeedSetting=5000; 
+      break;
+    }
+  case FLOW_CAL_MODE:
+    {      
+      enLowFlowCalibrationStep=INIT_FLOW_CALIB_TEST;
+      bHighFlowCalibrationInProgress=FALSE;
+      stTemporayLUTFlowSensor.uiLUT_TableSize=0;
+      uiCalibrationTimeOut=(TIME_OUT_BLOWER_HANDSET_COMM*20); // 2s
+      break;
+    }
+  case PRESSURE_CAL_MODE:
+    {      
+      enPressureCalibrationStep=INIT_PRESSURE_CALIB_TEST;
+      uiCalibrationTimeOut=(TIME_OUT_BLOWER_HANDSET_COMM*20); // 2s
+      break;
+    }
+  case PRESSURE_CST_MODE:
+    {
+      uiMLT_PressureSetPoint=10;
+      lIntegral_Pressure_I=0;
+      bMaxPIOutputPressureI=FALSE;
+      bMinPIOutputPressureI=FALSE;  
+     
+      #ifdef MOTOR_LIFE_TESTING
+      uiMLT_EnableAlarm=5000;  // 5s before enabling alarm            
+      uiAverageMonitoringMLT=MLT_AVERAGE_MONITORING;    
+      ulMLT_SumSpeedMes=0;
+      ulMLT_SumCurrentMes=0;
+      ulMLT_SumTemperatureMes=0;
+      ulMLT_SumBlowerVoltage=0;
+      #endif  // #ifdef MOTOR_LIFE_TESTING
+      break;
+    }
+  }   
+  enPreviousMode=enVentilationMode; 
+}
+
+
+/*******************************************************************************
+* Function Name  : StopAllActuators
+* Description    : Stop all actuators
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void StopAllActuators(void)
+{ 
+  // Stop main blower
+  SS_Xclose(mdrv);   
+
+  // Valve OFF
+  SS_Xputdw(act, EV_CTL|FLAG_ACTIONER_OFF);      
+}    
+
+/*******************************************************************************
+* Function Name  : CalculateHoseDrop
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+u16 CalculateHoseDrop(void)
+{
+  u16 hoseDrop = (u16)(10*(iBlowerFlowSmoothingMes/100.0f/60.0f * 0.5f));
+  return hoseDrop;
+}
+
+/*******************************************************************************
+* Function Name  : ManageCPAPVentilation
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageCPAPVentilation(void)
+{  
+  
+
+  
+  // *************************** UPDATE SETTINGS *******************************
+  if (ApplyNewVentilationMode()==TRUE)
+    return;
+          
+  // **************************** Cycle detection ******************************
+  // Test Synchronisation
+  /*if (iBlowerFlowSmoothingMesForTrigger<(-500) && ucVentilationCycle==INSPIRATION_CYCLE)  
+    ucVentilationCycle=EXPIRATION_CYCLE; */ 
+  int32_t peakP = 2;//(int32_t)uiVentilationSet[PS_CPAP_SET];
+  // Cycle detection  
+  if (ucVentilationCycle==INSPIRATION_CYCLE)
+  {
+    uiTiD++;
+    if(uiTiD < (0.1f * uiTiTyp))
+    {
+      peakP =(int32_t)( uiVentilationSet[PS_CPAP_SET] * ((uiTiD* 1.0f)/(0.1f * uiTiTyp)));
+    }
+    else if(uiTiD < (1.0f * uiTiTyp))
+    {
+      peakP = ((int32_t)uiVentilationSet[PS_CPAP_SET] - ((int32_t)(uiVentilationSet[PS_CPAP_SET] * (uiTiD * 1.0f)/(1.1f * uiTiTyp)))) + 20;
+    }
+    else
+    {
+      peakP = 2;
+    }
+    
+    if (uiTiD>5000 || (uiTiD>TiBaroSet_P_MIN && TestTriggerExpiratoire(20, uiVentilationSet[PS_CPAP_SET])==TRUE))
+    {
+      ucVentilationCycle=EXPIRATION_CYCLE;
+      uiPWMatTheEndOfInspiration = uiInspirationBlowerPWMTec;
+      if(uiTiD < 2000)
+      {
+        uiTiTyp = uiTiD;
+      }
+      else
+      {
+        uiTiTyp = 2000;
+      }
+      
+      uiTeD=0;      
+    }
+  }
+  else
+  {    
+    uiTeD++;
+    if (uiTeD>TE_SET_MAX) uiTeD=TE_SET_MAX;
+        
+    if (TestInspiratoryTrigger(TRUE, uiTeD, 15)==TRUE)
+    {
+      ucVentilationCycle=INSPIRATION_CYCLE;      
+      uiTiD=0;
+    }    
+  }
+  
+  // Barometric Mode : error computation
+  ControlPressure((int32_t)(peakP + CalculateHoseDrop()));
+}
+
+/*******************************************************************************
+* Function Name  : ControlPressure
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+int32_t previousError = 0;
+int32_t   lIntegralSum = 0;
+void ControlPressure(int32_t setPressure)//pressure in cmH2O*10
+{
+  int32_t   lPropTerm;                  
+  int32_t   lIntegralTerm;
+  int32_t   lDerivativeTerm;
+  int32_t   lOutputPressure;
+  
+  
+  int32_t lError = setPressure - uiProximalPressureMes;
+  
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
+  lIntegralTerm += (int32_t)(uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I] * lError);
+  lDerivativeTerm = (int32_t)(uiTechnicalDataSet[KP_FLOW_I]*(lError - previousError/1000));
+  previousError = lError;
+  
+  // Close loop in pressure
+  if ((lIntegralTerm + lIntegralSum) > INTEGRAL_MAX) 
+    {
+      lIntegralSum = INTEGRAL_MAX;       
+    }
+  else if ((lIntegralTerm - lIntegralSum)< INTEGRAL_MIN)
+    {
+      lIntegralSum = INTEGRAL_MIN;       
+    }
+   else
+    {
+      lIntegralSum += lIntegralTerm;
+    }
+        
+  lOutputPressure = (lDerivativeTerm>>19) + (lIntegralSum>>16) + (lPropTerm>>13) ;
+   
+  lOutputPressure+=uiPWMatTheEndOfInspiration;
+  
+  
+  // Limit and Update blower PWM
+  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+    {
+    bMaxPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+    }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+    {
+    bMinPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+  else
+    {
+    bMaxPIOutputPressureI = FALSE;
+    bMinPIOutputPressureI = FALSE;
+    uiInspirationBlowerPWMTec = lOutputPressure;
+    }
+      
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
+  
+}
+
+
+/*******************************************************************************
+* Function Name  : DavidCControlPressure
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void DavidCControlPressure(int32_t setPressure)//pressure in cmH2O*10
+{
+  int32_t   lPropTerm;                  
+  int32_t   lIntegralTerm;
+  int32_t   lOutputPressure;
+  u16       uiFlowMaxInExpi;
+  int32_t lError = setPressure - uiProximalPressureMes;
+  
+  lIntegralTerm = (int32_t)Ki_Pressure_I * lError;  
+  if (Ki_Pressure_I<uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I]) 
+  {
+    Ki_Pressure_I++;
+  }
+          
+  // Close loop in pressure
+  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
+      lIntegral_Pressure_I = INTEGRAL_MAX;
+    else    
+      lIntegral_Pressure_I += lIntegralTerm;       
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
+      lIntegral_Pressure_I = INTEGRAL_MIN;
+    else
+      lIntegral_Pressure_I += lIntegralTerm;
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
+    lIntegral_Pressure_I += lIntegralTerm;
+  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
+    lIntegral_Pressure_I += lIntegralTerm;    
+       
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
+  
+  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
+   
+  lOutputPressure+=uiPWMatTheEndOfInspiration;
+  
+  // Flow limiting
+  uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
+  if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)
+  {      
+    // Impossible to maintain the peep (patient disconnection)
+    if (uiDisconnectionTime==0)
+    {        
+      if (fBlockCloseLoop==FALSE)
+        uiDisconnectionTimeInCPAP=CPAP_DISCONNECTION_TEST_PERIODICITY;
+      fBlockCloseLoop=TRUE;                                     // Block the close loop
+      if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
+        uiInspirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
+      else
+        uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+    else
+      uiDisconnectionTime--;  
+  }  
+  else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
+  {
+    // Good pressure : no disconnection
+    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;    
+    
+    if (fBlockCloseLoop==TRUE)
+    {
+      // The close loop was block before => unblock it
+      fBlockCloseLoop=FALSE;    
+      lIntegral_Pressure_I=0;
+      bMaxPIOutputPressureI = FALSE;
+      bMinPIOutputPressureI = FALSE;
+      uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;
+      return;
+    }
+    else if (iBlowerFlowSmoothingMes>=0)
+    {
+      // Record current PWM
+      uiMemoPWMDuringDisconnection=uiInspirationBlowerPWMTec;        
+    }
+  }
+        
+  // Unblock the close loop every 4s in case of none recorded PWM value
+  if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiDisconnectionTimeInCPAP==0) 
+  {
+    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
+    fBlockCloseLoop=FALSE;
+    lIntegral_Pressure_I=0;
+    bMaxPIOutputPressureI = FALSE;
+    bMinPIOutputPressureI = FALSE;
+    uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;
+    return;
+  }
+  
+  // Update Time counters 
+  if (uiDisconnectionTimeInCPAP!=0)
+    uiDisconnectionTimeInCPAP--;
+  
+  // Update blower PWM
+  if (fBlockCloseLoop==TRUE)
+  {      
+    bMaxPIOutputPressureI = TRUE; 
+  }
+  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+    {
+    bMaxPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+    }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+    {
+    bMinPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+  else
+    {
+    bMaxPIOutputPressureI = FALSE;
+    bMinPIOutputPressureI = FALSE;
+    uiInspirationBlowerPWMTec = lOutputPressure;
+    }
+      
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
+  
+}
+
+/*******************************************************************************
+* Function Name  : ManageOneCstPWM
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageOneCstPWM(void)
+{  
+  // *************************** UPDATE SETTINGS *******************************
+  if (ApplyNewVentilationMode()==TRUE)
+    return;
+  
+  // Update Blower Speed   
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
+}
+
+
+/*******************************************************************************
+* Function Name  : Manage2CstPWM
+* Description    : Manage Ti, Te, DAC, Blower, PID
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void Manage2CstPWM(void)
+{        
+  if (ucVentilationCycle==INSPIRATION_CYCLE)
+    {  
+    // ------------- INSPIRATION ------------      
+    SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);      
+    
+    // Inspiratoy time
+    uiTiD++;
+    if (uiTiD>=uiVentilationSet[TI_BARO_SET]) 
+      {
+      ucVentilationCycle=EXPIRATION_CYCLE;
+      uiTiD=0;
+      }
+    }
+  else
+    { 
+    // ------------- EXPIRATION ------------  
+    // *************************** UPDATE SETTINGS *******************************
+    if (ApplyNewVentilationMode()==TRUE)
+      return;
+    
+    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec); 
+        
+    // Expiratoy time
+    uiTeD++;
+    if (uiTeD>=uiTeBaroSet) 
+      {
+      ucVentilationCycle=INSPIRATION_CYCLE;
+      uiTeD=0;        
+      }
+    }
+}
+
+
+/*******************************************************************************
+* Function Name  : ManageCstSpeed
+* Description    : Manage constant speed ventilation
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageCstSpeed(void)
+{  
+  int32_t   lError;
+  int32_t   lPropTerm;                  
+  int32_t   lIntegralTerm;
+  int32_t   lOutputSpeed;
+  
+  // *************************** UPDATE SETTINGS *******************************
+  if (ApplyNewVentilationMode()==TRUE)
+    return;
+  
+  // Update settings
+  if (uiBlowerSpeedSetting<uiBlowerSpeedSet) 
+    uiBlowerSpeedSetting+=10;      
+  else if (uiBlowerSpeedSetting>uiBlowerSpeedSet) 
+    uiBlowerSpeedSetting-=10;      
+    
+  uiTiD++;
+  if ((uiTiD%10)==0)
+  {
+    // Barometric Mode : error computation
+    lError=(int32_t)uiBlowerSpeedSetting-(int32_t)uiBlowerSpeedMes;
+    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_SPEED_I_TEC] * lError;  
+            
+    // Close loop in pressure
+    if ((lIntegral_Speed_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputSpeedI==FALSE)) 
+      {
+      if ((lIntegral_Speed_I + lIntegralTerm) <0)
+        lIntegral_Speed_I = INTEGRAL_MAX;
+      else    
+        lIntegral_Speed_I += lIntegralTerm;       
+      }
+    else if ((lIntegral_Speed_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputSpeedI==FALSE)) 
+      {
+      if ((lIntegral_Speed_I + lIntegralTerm)>0)
+        lIntegral_Speed_I = INTEGRAL_MIN;
+      else
+        lIntegral_Speed_I += lIntegralTerm;
+      }
+    else if ((lIntegral_Speed_I<=0) && (lIntegralTerm>=0))
+      lIntegral_Speed_I += lIntegralTerm;
+    else if ((lIntegral_Speed_I>=0) && (lIntegralTerm<=0))    
+      lIntegral_Speed_I += lIntegralTerm;    
+         
+    lPropTerm = (int32_t)uiTechnicalDataSet[KP_SPEED_I_TEC] * lError;
+    lOutputSpeed = (lIntegral_Speed_I>>16) + (lPropTerm>>13);
+              
+    if (lOutputSpeed>=((int32_t)MAX_VOLTAGE_REF))
+      {
+      bMaxPIOutputSpeedI = TRUE; 
+      uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+      }
+    else if (lOutputSpeed<((int32_t)MIN_VOLTAGE_REF))
+      {
+      bMinPIOutputSpeedI = TRUE; 
+      uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+      }
+    else
+      {
+      bMaxPIOutputSpeedI = FALSE;
+      bMinPIOutputSpeedI = FALSE;
+      uiInspirationBlowerPWMTec = lOutputSpeed;
+      }
+    SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);   
+  }
+}
+
+/*******************************************************************************
+* Function Name  : ManageFlowCalibration
+* Description    : Manage Low flow calibration
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageFlowCalibration(void)
+{
+  char          cCharValue;
+  char          szTempBuf[SIZE_RX_BUFFER_PF300];
+  
+  /*  
+  #ifdef  USE_TSI_4040
+  switch(enTSICommScheduler)
+  {
+  default:
+  case TSI_SET_TYPE_OF_GAS:
+    {
+      // Send Type of Gas command                              
+      ucTSICommand=TSI_SEND_GAS_TYPE_AIR_CMD;
+      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
+      {
+        enTSICommScheduler=TSI_CHECK_ANSWER;
+        enTSIGoBackToStep=TSI_SET_FLOW_UNIT;                  
+      }
+      break;
+    }   
+  case TSI_SET_FLOW_UNIT:
+    {
+      // Send Type of Gas command                              
+      ucTSICommand=TSI_SEND_FLOW_UNIT_STANDARD_CMD;
+      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
+      {
+        enTSICommScheduler=TSI_CHECK_ANSWER;
+        enTSIGoBackToStep=TSI_SET_SAMPLE_TIME;                  
+      }
+      break;      
+    }  
+  case TSI_SET_SAMPLE_TIME:
+    {
+      // Send sample time
+      ucTSICommand=TSI_SEND_SAMPLE_TIME_10MS_CMD;
+      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
+      {
+        enTSICommScheduler=TSI_CHECK_ANSWER;
+        enTSIGoBackToStep=TSI_READ_FLOW;                  
+      }
+      break;      
+    }  
+  case TSI_READ_FLOW:
+    {
+      // Send sample time
+      ucTSICommand=TSI_SEND_READ_FLOW_CMD;
+      if (SS_Xputdw(tsi, &ucTSICommand)==TRUE)
+      {
+        enTSICommScheduler=TSI_CHECK_ANSWER;
+        enTSIGoBackToStep=TSI_CYCLE_DETECTION;                  
+      }
+      break;      
+    } 
+  case TSI_CYCLE_DETECTION:
+    {
+      uiBlowerFlow=iFlowFromTSI;
+      break;
+    }
+  case TSI_CHECK_ANSWER:
+    {                      
+      opstatus=SS_Xgetw(tsi, &uiDummy);        
+      if (opstatus==OPSTATUS_OK)
+      {
+        enTSICommScheduler=enTSIGoBackToStep;
+      }
+      else if (opstatus==OPSTATUS_FAIL)
+      {
+        enTSICommScheduler=TSI_SET_TYPE_OF_GAS;
+      }        
+      break;  
+    }
+  }
+  #endif  // #ifdef  USE_TSI_4040
+  */
+    
+  switch(enLowFlowCalibrationStep)
+  {
+  case INIT_FLOW_CALIB_TEST:
+    {
+      // Init comm with PF300 => wait 2s before sending first command to PF300
+      // We need to wait for this delay in order to the handset to activate its transparent mode
+      if (uiCalibrationTimeOut==0)
+      {              
+        bDisableMaroubraCommCommunication=TRUE;
+        
+        // Prepare command to PF300 
+        UpdateBufferToSend((char*)szPF300_CmdSwitchOffEcho);       
+        enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;        
+        strcpy(szExpectedAnswerFromPF300, szPF300_AnswerSwitchOffEcho);
+        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerSwitchOffEcho);
+        enGoBackToStep=SET_GAS_TYPE;                  
+      } 
+      else
+      {
+        uiCalibrationTimeOut--;
+      }
+      break;
+    }   
+  case SET_GAS_TYPE:
+    {
+      // Prepare command to PF300 
+      UpdateBufferToSend((char*)szPF300_SetAirGasType);               
+      enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;      
+      strcpy(szExpectedAnswerFromPF300, szPF300_AnswerAirGasType);
+      ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerAirGasType);
+      enGoBackToStep=SET_GAS_STANDARD;  
+      break;      
+    }
+  case SET_GAS_STANDARD:
+    {
+      // Prepare command to PF300 
+      UpdateBufferToSend((char*)szPF300_SetGasStandard);             
+      enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;      
+      strcpy(szExpectedAnswerFromPF300, szPF300_AnswerGasStandard);
+      ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerGasStandard);
+      enGoBackToStep=START_FLOW_READING;  
+      break;      
+    }  
+  case START_FLOW_READING:
+    {
+      // Set Min blower speed
+      uiMotorDutyCyleForFlowCalib=MIN_PI_OUTPUT;
+      SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
+      
+      // Init variable for flow sensor
+      uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_FLOW;              
+      ulSumFlowTicks=0;
+      uiFlowTicksSamplesCounter=0;
+      
+      // Next step
+      enLowFlowCalibrationStep=SEND_FLOW_COMMAND;  
+      break;
+    }
+  case SEND_FLOW_COMMAND:
+    {      
+      if (uiCalibrationTimeOut!=0)
+      {
+        uiCalibrationTimeOut--;
+        
+        if (uiCalibrationTimeOut<(SAMPLE_RATE_BETWEEN_TWO_FLOW>>1))
+        {
+          ulSumFlowTicks+=uiBlowerFlowRAWMes;
+          uiFlowTicksSamplesCounter++;        
+        }
+      }
+      else
+      {
+        // Prepare next command (Read Low Flow)
+        enLowFlowCalibrationStep=SEND_COMMAND_TO_PF300;
+        if (bHighFlowCalibrationInProgress==FALSE)
+        {
+          UpdateBufferToSend((char*)szPF300_ReadLowFlowCmd);                // %RM#1\r      
+          strcpy(szExpectedAnswerFromPF300, szPF300_ReadLowFlowAnswer);     // %RM#1$          
+          ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadLowFlowAnswer);
+        }
+        else
+        {
+          UpdateBufferToSend((char*)szPF300_ReadHighFlowCmd);               // %RM#0\r      
+          strcpy(szExpectedAnswerFromPF300, szPF300_ReadHighFlowAnswer);    // %RM#0$          
+          ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadHighFlowAnswer);
+        }
+        enGoBackToStep=READ_FLOW_VALUE;                              
+      }
+      break;
+    }      
+  case READ_FLOW_VALUE: 
+    {                   
+      if (uiFlowTicksSamplesCounter!=0)
+      {
+        // Read PF300 flow (l/min)
+        strcpy(szTempBuf, &szAnswerFromPF300[ucNumberOfBytesToCheckFromPF300Answer]);
+        
+        // Store value of flow
+        if (stTemporayLUTFlowSensor.uiLUT_TableSize<LOW_FLOW_CALIB_NUMBER_OF_SAMPLES)
+          stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]=(unsigned int)atoi(szTempBuf);
+        else
+          stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]=(unsigned int)atoi(szTempBuf)*10;
+        
+        // Store ticks value
+        stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize]=ulSumFlowTicks/uiFlowTicksSamplesCounter;
+        uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_FLOW;        
+        ulSumFlowTicks=0; 
+        uiFlowTicksSamplesCounter=0;                                                
+                             
+        // Check if current flow <0.1l/min
+        if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<10)
+        {
+          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+          break;
+        }
+            
+        // Check if the last low flow is higher than 20l/min or lower than 2l/min
+        if (stTemporayLUTFlowSensor.uiLUT_TableSize==(LOW_FLOW_CALIB_NUMBER_OF_SAMPLES-1))
+        {
+          // Check if the last low flow is higher than 20l/min or lower than 2l/min
+          if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]>2000 || stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<200)
+          {
+            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+            break;
+          }
+        }
+        
+        // Next flow sample
+        if (stTemporayLUTFlowSensor.uiLUT_TableSize==LOW_FLOW_CALIB_NUMBER_OF_SAMPLES && stTemporayLUTFlowSensor.uiFlowValue[LOW_FLOW_CALIB_NUMBER_OF_SAMPLES]<(stTemporayLUTFlowSensor.uiFlowValue[LOW_FLOW_CALIB_NUMBER_OF_SAMPLES-1]+500))
+        {
+          // No enough flow margin between the last value of the low flow and the first value of the high flow
+        }             
+        else if (stTemporayLUTFlowSensor.uiLUT_TableSize!=0 && stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize]<(stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize-1]+50))
+        {
+          // No enough margin between two consecutives flow
+        }
+        else if (stTemporayLUTFlowSensor.uiLUT_TableSize!=0 && stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize]<=stTemporayLUTFlowSensor.uiFlowSensorTicks[stTemporayLUTFlowSensor.uiLUT_TableSize-1])
+        {
+          // Same or less ticks between two consecutives flow
+          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+          break;
+        }
+        else
+        {
+          stTemporayLUTFlowSensor.uiLUT_TableSize++;
+          if (stTemporayLUTFlowSensor.uiFlowValue[stTemporayLUTFlowSensor.uiLUT_TableSize-1]>=14000)
+          {
+            // End of calib => check the number of samples
+            if (stTemporayLUTFlowSensor.uiLUT_TableSize>(FLOW_CALIB_NUMBER_OF_SAMPLES>>1))
+            {
+              enLowFlowCalibrationStep=PREPARE_SUCCESS_COMMAND;
+              
+              // Transfer the temporary LUT in the definitive LUT
+              stLUTFlowSensor=stTemporayLUTFlowSensor;
+            }
+            else
+            {
+              enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+            }
+            break;
+          }
+          else if (stTemporayLUTFlowSensor.uiLUT_TableSize>FLOW_CALIB_NUMBER_OF_SAMPLES)
+          {             
+            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+            break;
+          }
+        }
+        
+        // Prepare next flow reading
+        if (stTemporayLUTFlowSensor.uiLUT_TableSize<LOW_FLOW_CALIB_NUMBER_OF_SAMPLES)
+        {
+          // New motor speed
+          uiMotorDutyCyleForFlowCalib+=20;
+          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;
+        }
+        else if (stTemporayLUTFlowSensor.uiLUT_TableSize==LOW_FLOW_CALIB_NUMBER_OF_SAMPLES && bHighFlowCalibrationInProgress==FALSE)
+        {
+          // Min speed for motor
+          uiMotorDutyCyleForFlowCalib=MIN_PI_OUTPUT;
+          SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
+          enLowFlowCalibrationStep=SEND_HIGH_FLOW_CALIB_REQUEST;          
+          break;
+        }
+        else
+        {
+          // New motor speed
+          uiMotorDutyCyleForFlowCalib+=10;
+          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;          
+        }
+        
+        // Update motor speed
+        if (uiMotorDutyCyleForFlowCalib<MAX_PI_OUTPUT)
+        {
+          SS_Xputdw(mdrv, uiMotorDutyCyleForFlowCalib);
+        }
+        else
+        {
+          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+          break;
+        }                                        
+      }
+      else    // if (uiFlowTicksSamplesCounter!=0)
+      {
+        enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+      }            
+      break;
+    }
+  case SEND_HIGH_FLOW_CALIB_REQUEST:
+    {
+      if (TransferCommandToHandset((char*)szRequestHighFlowCalib)==TRUE)
+        enLowFlowCalibrationStep=WAIT_FOR_HIGH_FLOW_CALIB_ACK;       
+      break;
+    }
+  case WAIT_FOR_HIGH_FLOW_CALIB_ACK:
+    {
+      // Wait for acknownledge from handset
+      if (ReadByteReceive(&cCharValue)==TRUE)
+      {                          
+        if (cCharValue=='@')
+        {
+          // Continue flow calibration
+          bHighFlowCalibrationInProgress=TRUE;
+          enLowFlowCalibrationStep=SEND_FLOW_COMMAND;
+        }
+        else
+          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+      }
+      break;
+    }
+  case PREPARE_FAILURE_COMMAND:
+    {
+      if (TransferCommandToHandset((char*)szEndOfCalibFailed)==TRUE)
+        enLowFlowCalibrationStep=END_OF_CALIBRATION;
+      break;
+    }
+  case PREPARE_SUCCESS_COMMAND:
+    {
+      if (TransferCommandToHandset((char*)szEndOfCalibOK)==TRUE)
+        enLowFlowCalibrationStep=END_OF_CALIBRATION;      
+      break;
+    }
+  case SEND_COMMAND_TO_PF300:
+    {
+      // Send a byte every 1ms
+      if (TransferBufferToPF300()==TRUE)
+      {      
+        // Buffer sent !!
+        if (ucNumberOfBytesToCheckFromPF300Answer!=0)
+        {
+          // Check answer from PF300
+          ucIndexAnswerFromPF300=0;
+          uiCalibrationTimeOut=TIME_OUT_RECEPTION_PACKET_FROM_PF300;
+          enLowFlowCalibrationStep=CHECK_COMMAND_FROM_PF300;
+        }
+        else
+          enLowFlowCalibrationStep=enGoBackToStep;
+      }
+      break;
+    }
+  case CHECK_COMMAND_FROM_PF300:
+    {
+      if (uiCalibrationTimeOut==0)
+      {
+        // Time-out in reception !!
+        ucIndexAnswerFromPF300=0;
+        enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+      }
+      else if (ReadByteReceive(&cCharValue)==TRUE)
+      {                            
+        // Check last byte received
+        if (cCharValue=='\r')
+        {
+          // End of answer => check buffer content
+          ucIndexAnswerFromPF300=0;
+          strcpy(szTempBuf, szAnswerFromPF300);
+          szTempBuf[ucNumberOfBytesToCheckFromPF300Answer]=0;
+          if (strcmp(szTempBuf, szExpectedAnswerFromPF300)==0)
+          {
+            // Buffer OK !!
+            enLowFlowCalibrationStep=enGoBackToStep;
+          }
+          else
+          {
+            // Buffer wrong !!
+            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+          }
+        }
+        else if (cCharValue=='?')
+        {
+          // PF300 is lost => end of calibration
+          ucIndexAnswerFromPF300=0;
+          enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+        }                       
+        else
+        {
+          // Store byte from PF300 into buffer
+          szAnswerFromPF300[ucIndexAnswerFromPF300++]=cCharValue;
+          if (ucIndexAnswerFromPF300>=SIZE_RX_BUFFER_PF300)
+          {
+            // Answer too long !!
+            ucIndexAnswerFromPF300=0;
+            enLowFlowCalibrationStep=PREPARE_FAILURE_COMMAND;
+          }
+          else
+          {
+            // Add 0 at the end of the string
+            szAnswerFromPF300[ucIndexAnswerFromPF300]=0; 
+          }
+        }
+      }
+      else
+      {
+        // No byte received !!
+        uiCalibrationTimeOut--;
+      }
+      break;  
+    }
+  default:  
+  case END_OF_CALIBRATION:
+    {      
+      uiTechnicalDataSet[START_STOP_VENTILATION]=0; 
+      bDisableMaroubraCommCommunication=FALSE;
+      break;
+    }
+  }         // switch
+  
+  // Every 300ms, send '@*' to inform the handset that the blower works properly
+  if (uiImHereMsgTimer==0)
+  {
+    if (enLowFlowCalibrationStep!=SEND_COMMAND_TO_PF300)
+    {
+      uiImHereMsgTimer=300;
+      TransferCommandToHandset((char*)szImHere);
+    }
+  }
+  else
+    uiImHereMsgTimer--;
+}
+
+/*******************************************************************************
+* Function Name  : ManagePressureCalibration
+* Description    : Manage pressure calibration
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManagePressureCalibration(void)
+{
+  char          cCharValue;
+  char          szTempBuf[SIZE_RX_BUFFER_PF300];
+  u16           uiCalibPressureADCValue;
+  u16           uiCalibPressureValue;
+  u16           uiCalibPressureGain;
+  
+  switch(enPressureCalibrationStep)
+  {
+  case INIT_PRESSURE_CALIB_TEST:
+    {
+      // Init comm with PF300 => wait 2s before sending first command to PF300
+      // We need to wait for this delay in order to the handset to activate its transparent mode
+      if (uiCalibrationTimeOut==0)
+      {              
+        bDisableMaroubraCommCommunication=TRUE;
+                                    
+        // Prepare command to PF300 
+        UpdateBufferToSend((char*)szPF300_CmdSwitchOffEcho);                     
+        strcpy(szExpectedAnswerFromPF300, szPF300_AnswerSwitchOffEcho);
+        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_AnswerSwitchOffEcho);
+        enPressureCalibrationStep=PRESSURE_CALIB_SEND_COMMAND_TO_PF300;  
+        enPressureCalibGoBackToStep=START_PRESSURE_READING;                  
+      } 
+      else
+      {
+        uiCalibrationTimeOut--;
+      }
+      break;
+    } 
+  case START_PRESSURE_READING:
+  {
+    // Set blower speed
+    SS_Xputdw(mdrv, 600);
+        
+    // Init variable for flow sensor
+    uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_PRESSURE;              
+    ulSumPressureTicks=0;
+    uiPressureTicksSamplesCounter=0;  
+    
+    enPressureCalibrationStep=SEND_PRESSURE_COMMAND;
+    break;
+  }
+  case SEND_PRESSURE_COMMAND:
+    {      
+      if (uiCalibrationTimeOut!=0)
+      {
+        uiCalibrationTimeOut--;
+        
+        if (uiCalibrationTimeOut<2000)
+        {
+          ulSumPressureTicks+=uiProximalPressureADCMes;
+          uiPressureTicksSamplesCounter++;        
+        }
+      }
+      else
+      {
+        // Prepare next command        
+        UpdateBufferToSend((char*)szPF300_ReadPdiffCmd);               
+        strcpy(szExpectedAnswerFromPF300, szPF300_ReadPdiffAnswer);    
+        ucNumberOfBytesToCheckFromPF300Answer=strlen(szPF300_ReadPdiffAnswer);        
+        enPressureCalibrationStep=PRESSURE_CALIB_SEND_COMMAND_TO_PF300;
+        enPressureCalibGoBackToStep=READ_PRESSURE_VALUE;
+      }
+      break;
+    }      
+  case READ_PRESSURE_VALUE: 
+    {                   
+      if (uiPressureTicksSamplesCounter!=0)
+      {
+        // Read PF300 pressure
+        strcpy(szTempBuf, &szAnswerFromPF300[ucNumberOfBytesToCheckFromPF300Answer]);
+        
+        // Store value of Pressure        
+        uiCalibPressureValue=(unsigned int)atoi(szTempBuf);
+        
+        // Store ticks value
+        uiCalibPressureADCValue=ulSumPressureTicks/uiPressureTicksSamplesCounter;
+        uiCalibrationTimeOut=SAMPLE_RATE_BETWEEN_TWO_PRESSURE;        
+        ulSumPressureTicks=0; 
+        uiPressureTicksSamplesCounter=0;                                                
+                             
+        // Check if current pressure<10cmH20
+        if (uiCalibPressureValue<1000)
+        {
+          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+          break;
+        }
+            
+        // Compute pressure gain
+        uiCalibPressureGain=(10000UL*(uiCalibPressureADCValue-uiTechnicalDataSet[PPROX_OFFSET_TEC]))/uiCalibPressureValue; 
+        uiCalibPressureGain+=5;
+        uiCalibPressureGain/=10;
+        
+        // Check pressure gain range  
+        if (uiCalibPressureGain<Tec_GainPprox_MIN || uiCalibPressureGain>Tec_GainPprox_MAX)
+        {
+          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+        }
+        else
+        {
+          enPressureCalibrationStep=PRESSURE_CALIB_SUCCESS_COMMAND;
+          
+          // Transfer the temporary LUT in the definitive LUT
+          uiTechnicalDataSet[PPROX_GAIN_TEC]=uiCalibPressureGain;
+        }                                  
+      }
+      else    // if (uiPressureTicksSamplesCounter!=0)
+      {
+        enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+      }            
+      break;
+    }  
+  case PRESSURE_CALIB_FAILURE_COMMAND:
+    {
+      if (TransferCommandToHandset((char*)szEndOfCalibFailed)==TRUE)
+        enPressureCalibrationStep=PRESSURE_CALIB_END_OF_CALIBRATION;
+      break;
+    }
+  case PRESSURE_CALIB_SUCCESS_COMMAND:
+    {
+      if (TransferCommandToHandset((char*)szEndOfCalibOK)==TRUE)
+        enPressureCalibrationStep=PRESSURE_CALIB_END_OF_CALIBRATION;      
+      break;
+    }
+  case PRESSURE_CALIB_SEND_COMMAND_TO_PF300:
+    {
+      // Send a byte every 1ms
+      if (TransferBufferToPF300()==TRUE)
+      {      
+        // Buffer sent !!
+        if (ucNumberOfBytesToCheckFromPF300Answer!=0)
+        {
+          // Check answer from PF300
+          ucIndexAnswerFromPF300=0;
+          uiCalibrationTimeOut=TIME_OUT_RECEPTION_PACKET_FROM_PF300;
+          enPressureCalibrationStep=PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300;
+        }
+        else
+          enPressureCalibrationStep=enPressureCalibGoBackToStep;
+      }
+      break;
+    }
+  case PRESSURE_CALIB_CHECK_COMMAND_FROM_PF300:
+    {
+      if (uiCalibrationTimeOut==0)
+      {
+        // Time-out in reception !!
+        ucIndexAnswerFromPF300=0;
+        enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+      }
+      else if (ReadByteReceive(&cCharValue)==TRUE)
+      {                            
+        // Check last byte received
+        if (cCharValue=='\r')
+        {
+          // End of answer => check buffer content
+          ucIndexAnswerFromPF300=0;
+          strcpy(szTempBuf, szAnswerFromPF300);
+          szTempBuf[ucNumberOfBytesToCheckFromPF300Answer]=0;
+          if (strcmp(szTempBuf, szExpectedAnswerFromPF300)==0)
+          {
+            // Buffer OK !!
+            enPressureCalibrationStep=enPressureCalibGoBackToStep;
+          }
+          else
+          {
+            // Buffer wrong !!
+            enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+          }
+        }
+        else if (cCharValue=='?')
+        {
+          // PF300 is lost => end of calibration
+          ucIndexAnswerFromPF300=0;
+          enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+        }                       
+        else
+        {
+          // Store byte from PF300 into buffer
+          szAnswerFromPF300[ucIndexAnswerFromPF300++]=cCharValue;
+          if (ucIndexAnswerFromPF300>=SIZE_RX_BUFFER_PF300)
+          {
+            // Answer too long !!
+            ucIndexAnswerFromPF300=0;
+            enPressureCalibrationStep=PRESSURE_CALIB_FAILURE_COMMAND;
+          }
+          else
+          {
+            // Add 0 at the end of the string
+            szAnswerFromPF300[ucIndexAnswerFromPF300]=0; 
+          }
+        }
+      }
+      else
+      {
+        // No byte received !!
+        uiCalibrationTimeOut--;
+      }
+      break;  
+    }
+  default:  
+  case PRESSURE_CALIB_END_OF_CALIBRATION:
+    {      
+      uiTechnicalDataSet[START_STOP_VENTILATION]=0; 
+      bDisableMaroubraCommCommunication=FALSE;
+      break;
+    }
+  }         // switch
+  
+  // Every 300ms, send '@*' to inform the handset that the blower works properly
+  if (uiImHereMsgTimer==0)
+  {
+    if (enPressureCalibrationStep!=PRESSURE_CALIB_SEND_COMMAND_TO_PF300)
+    {
+      uiImHereMsgTimer=300;
+      TransferCommandToHandset((char*)szImHere);
+    }
+  }
+  else
+    uiImHereMsgTimer--;
+}
+
+
+/*******************************************************************************
+* Function Name  : ManageCstPressure
+* Description    : Manage constant pressure
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageCstPressure(void)
+{
+  int32_t   lError;
+  int32_t   lPropTerm;                  
+  int32_t   lIntegralTerm;
+  int32_t   lOutputPressure;
+
+  
+  // Barometric Mode : error computation
+  lError=(int32_t)uiMLT_PressureSetPoint-(int32_t)uiProximalPressureMes;
+  lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_CPAP_VENTED_PRESSURE_I] * lError;  
+  if (uiMLT_PressureSetPoint<uiVentilationSet[PI_SET]) uiMLT_PressureSetPoint++;
+             
+  // Close loop in pressure
+  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
+      lIntegral_Pressure_I = INTEGRAL_MAX;
+    else    
+      lIntegral_Pressure_I += lIntegralTerm;       
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
+      lIntegral_Pressure_I = INTEGRAL_MIN;
+    else
+      lIntegral_Pressure_I += lIntegralTerm;
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
+    lIntegral_Pressure_I += lIntegralTerm;
+  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
+    lIntegral_Pressure_I += lIntegralTerm;    
+    
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_CPAP_VENTED_PRESSURE_I] * lError;
+  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
+
+  // Add constante value (PWM at the end of the previous inspiration)    
+  //lOutputPressure+=300; 
+   
+  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+  {
+    bMaxPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+  }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+  {
+    bMinPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+  }
+  else
+  {
+    bMaxPIOutputPressureI = FALSE;
+    bMinPIOutputPressureI = FALSE;
+    uiInspirationBlowerPWMTec = lOutputPressure;
+  }
+    
+  // Update Blower Speed   
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);     
+  
+  // Monitoring and Alarm (every 1s)
+  #ifdef MOTOR_LIFE_TESTING
+    if (uiAverageMonitoringMLT==0)
+    {
+      uiAverageBlowerSpeedMes=ulMLT_SumSpeedMes/MLT_AVERAGE_MONITORING;
+      uiBreathBlowerCurrentMes=ulMLT_SumCurrentMes/MLT_AVERAGE_MONITORING;
+      uiAverateMotorTempMes=ulMLT_SumTemperatureMes/MLT_AVERAGE_MONITORING;
+      uiAverageMotorVoltage=ulMLT_SumBlowerVoltage/MLT_AVERAGE_MONITORING;
+      
+      ulMLT_SumSpeedMes=0;
+      ulMLT_SumCurrentMes=0;
+      ulMLT_SumTemperatureMes=0;
+      ulMLT_SumBlowerVoltage=0;
+      uiAverageMonitoringMLT=MLT_AVERAGE_MONITORING;
+    }
+    else
+    {
+      ulMLT_SumSpeedMes+=uiBlowerSpeedMes;
+      ulMLT_SumCurrentMes+=uiBlowerCurrentMes;
+      ulMLT_SumTemperatureMes+=uiTechnicalDataMes[MOTOR_TEMPERATURE_TEC_MES];
+      ulMLT_SumBlowerVoltage+=uiTechnicalDataMes[MOTOR_VOLTAGE_TEC_MES];
+      uiAverageMonitoringMLT--;
+    }
+    
+    // Alarms management
+    if (uiMLT_EnableAlarm==0)
+    {
+      // High Speed alarm
+      if (uiAverageBlowerSpeedMes>uiTechnicalDataSet[MLT_HIGH_SPEED_TEC])
+        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_SPEED_ALARM_MASK;
+      
+      // Low Speed alarm
+      if (uiAverageBlowerSpeedMes<uiTechnicalDataSet[MLT_LOW_SPEED_TEC])
+        uiFlagsAlarm[ALARM_FLAGS2]|=LOW_BLOWER_SPEED_ALARM_MASK;
+        
+      // High blower current alarm
+      if (uiBreathBlowerCurrentMes>uiTechnicalDataSet[MLT_HIGH_CURRENT_TEC])
+        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_CURRENT_ALARM_MASK;
+      
+      // High Blower temperature
+      if (uiAverateMotorTempMes>uiTechnicalDataSet[MLT_HIGH_TEMPERATURE_TEC])
+        uiFlagsAlarm[ALARM_FLAGS2]|=HIGH_BLOWER_TEMP_ALARM_MASK;
+
+      // Low Blower temperature
+      if (uiAverateMotorTempMes<100)
+        uiFlagsAlarm[ALARM_FLAGS2]|=LOW_BLOWER_TEMP_ALARM_MASK;
+      
+      // High Blower Flow
+      if (iBlowerFlowSmoothingMesForTrigger>uiTechnicalDataSet[MLT_HIGH_FLOW_TEC] || iBlowerFlowSmoothingMesForTrigger<uiTechnicalDataSet[MLT_LOW_FLOW_TEC])
+        uiFlagsAlarm[ALARM_FLAGS2]|=OOR_BLOWER_FLOW_ALARM_MASK;
+    }
+    else
+      uiMLT_EnableAlarm--;
+  #endif  // MOTOR_LIFE_TESTING
+}
+
+
+/*******************************************************************************
+* Function Name  : ManagePACVVentilation
+* Description    : Manage Bilevel ventilation
+* Input          : bPSMode=true in PS mode, false in PI mode
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManagePACVVentilation(bool bPSMode)
+{
+int32_t   lError;
+int32_t   lPropTerm;                  
+int32_t   lIntegralTerm;
+int32_t   lOutputPressure;
+u16       uiPressureSetPoint;
+u16       uiTiMax;
+u16       uiTiMin;
+//u16       uiTeMax;
+u16       uiFlowMaxInExpi;
+
+if (ucVentilationCycle==INSPIRATION_CYCLE)
+  {  
+  // ---------------------------------------------------------------------------
+  // -                              INSPIRATION                                -
+  // --------------------------------------------------------------------------              
+                  
+  // Ti et pressure set point management
+  if (bPSMode==TRUE)   
+  {
+    uiPressureSetPoint=uiVentilationSet[PS_SET]; 
+    uiTiMax=uiVentilationSet[TI_MAX_SET]; 
+  }
+  else    
+  {
+    uiPressureSetPoint=uiVentilationSet[PI_SET];
+    uiTiMax=uiVentilationSet[TI_BARO_SET];    
+  }
+  
+  // Compute Timin
+  if (uiPatientType==PATIENT_ADULT)   
+    uiTiMin=TiBaroSet_A_MIN;
+  else
+    uiTiMin=TiBaroSet_P_MIN;
+   
+  // Limit the pressure setting
+  if (uiVentilationSet[HIGH_PRESSURE_ALARM_SET]<uiPressureSetPoint)
+    uiPressureSetPoint=uiVentilationSet[HIGH_PRESSURE_ALARM_SET];
+  
+  if (uiTiD==0) 
+  { 
+    // Management Expiratory Trigger    
+    ucTempoTriggerExpiAuto=TEMPO_TRIGGER_EXPI;
+    ucExpiTriggerTreshold=MIN_THRESHOLD_EXPI_TRIGGER_AUTO;
+    
+    // Management Inspiratory slope    
+    switch(uiVentilationSet[SLOPE_BARO_SET])
+    {
+      default:
+      case 1:
+      {
+        // Slope of 5ms/hPa => 0.2hPa/ms
+        uiIpapSettingTemp=uiVentilationSet[PEEP_SET]+2;                    
+        break;
+      }
+      case 2:
+      {
+        ucIndexTableSlope=0;
+        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope2Table[ucIndexTableSlope++])/100;
+        break;
+      }
+      case 3:
+      {
+        ucIndexTableSlope=0;
+        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope3Table[ucIndexTableSlope++])/100;
+        break;
+      }
+      case 4:
+      {
+        ucIndexTableSlope=0;
+        uiIpapSettingTemp=(uiPressureSetPoint*ucSlope4Table[ucIndexTableSlope++])/100;
+        break;
+      }
+    }
+  }
+  else 
+  {
+    // Management Inspiratory slope 
+    switch(uiVentilationSet[SLOPE_BARO_SET])
+    {
+      default:
+      case 1:
+      {
+        // Slope of 5ms/hPa => 0.2hPa/ms
+        uiIpapSettingTemp+=2;                                   
+        if (uiIpapSettingTemp>uiPressureSetPoint) 
+          uiIpapSettingTemp=uiPressureSetPoint;
+        break;
+      }
+      case 2:
+      {
+        if (ucIndexTableSlope<SIZE_SLOPE2_TABLE && (uiTiD%10)==0)
+          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope2Table[ucIndexTableSlope++])/100;
+        break;
+      }
+      case 3:
+      {
+        if (ucIndexTableSlope<SIZE_SLOPE3_TABLE && (uiTiD%10)==0)
+          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope3Table[ucIndexTableSlope++])/100;
+        break;
+      }
+      case 4:
+      {
+        if (ucIndexTableSlope<SIZE_SLOPE4_TABLE && (uiTiD%10)==0)
+          uiIpapSettingTemp=(uiPressureSetPoint*ucSlope4Table[ucIndexTableSlope++])/100;
+        break;
+      }
+    }        
+  }     
+  
+  // Barometric Mode : error computation
+  lError=(int32_t)uiIpapSettingTemp-(int32_t)uiProximalPressureMes;
+  if (fFirstCycleInspi==FALSE) 
+    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_I] * lError;
+  else
+  {
+    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_I]>>2) * lError;
+    uiPWMatTheEndOfInspiration=uiExpirationBlowerPWMTec;
+  }
+             
+  // Close loop in pressure
+  if ((lIntegral_Pressure_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm) <0)
+      lIntegral_Pressure_I = INTEGRAL_MAX;
+    else    
+      lIntegral_Pressure_I += lIntegralTerm;       
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureI==FALSE)) 
+    {
+    if ((lIntegral_Pressure_I + lIntegralTerm)>0)
+      lIntegral_Pressure_I = INTEGRAL_MIN;
+    else
+      lIntegral_Pressure_I += lIntegralTerm;
+    }
+  else if ((lIntegral_Pressure_I<=0) && (lIntegralTerm>=0))
+    lIntegral_Pressure_I += lIntegralTerm;
+  else if ((lIntegral_Pressure_I>=0) && (lIntegralTerm<=0))    
+    lIntegral_Pressure_I += lIntegralTerm;    
+    
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_I] * lError;
+  lOutputPressure = (lIntegral_Pressure_I>>16) + (lPropTerm>>13);
+
+  // Add constante value (PWM at the end of the previous inspiration)    
+  lOutputPressure+=uiPWMatTheEndOfInspiration; 
+   
+  if (fAlarmPmax==TRUE || fAlarmVtiMax==TRUE)
+  {
+    bMaxPIOutputPressureI = TRUE; 
+  }
+  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+  {
+    bMaxPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+  }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+  {
+    bMinPIOutputPressureI = TRUE; 
+    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+  }
+  else
+  {
+    bMaxPIOutputPressureI = FALSE;
+    bMinPIOutputPressureI = FALSE;
+    uiInspirationBlowerPWMTec = lOutputPressure;
+  }
+    
+  // Update Blower Speed   
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);                                  
+              
+  // ************************ CYCLE MANAGEMENT *********************************
+  uiTiD++; 
+  if ((uiTiD>=uiTiMax) || 
+      (TestTriggerExpiratoire(uiVentilationSet[TRIG_E_SET], uiVentilationSet[PS_SET])==TRUE && uiTiD>uiVentilationSet[TI_MIN_SET] && bPSMode==TRUE) ||
+      (fAlarmPmax==TRUE   && uiTiD>uiTiMin) ||
+      (fAlarmVtiMax==TRUE && uiTiD>uiTiMin))
+    {   
+    // Beginning of the expiration  
+    if (fAlarmPmax==FALSE && fAlarmVtiMax==FALSE)
+    {
+      fFirstCycleInspi=FALSE;
+      uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;  
+    }
+    else
+    {
+      fFirstCycleInspi=TRUE;
+      uiPWMatTheEndOfInspiration=MIN_VOLTAGE_REF;
+    }
+    
+    ucVentilationCycle=EXPIRATION_CYCLE;
+    uiTiD=0;                              
+             
+    // Reset PI variables for next inspiration
+    lIntegral_Pressure_E=0;         
+    bMaxPIOutputPressureE=FALSE;
+    bMinPIOutputPressureE=FALSE;   
+    
+    fFirstCycleExpi=FALSE;     
+    }
+  }  
+else
+  { 
+  // ---------------------------------------------------------------------------
+  // -                               EXPIRATION                                -
+  // ---------------------------------------------------------------------------                    
+  
+  // *************************** UPDATE SETTINGS *******************************
+  if (ApplyNewVentilationMode()==TRUE)
+    return;
+      
+  // ******************** MAIN BLOWER MANAGEMENT *******************************  
+  if (uiVentilationSet[PEEP_SET]==0)
+  {
+    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
+  }
+  else
+  {
+    if (uiTeD==0) 
+    {         
+      // First blower current setting
+      uiEpapSettingTemp=uiVentilationSet[PI_SET]-2;                    // Slope of 5ms/hPa => 0.2hPa/ms
+    }
+    else 
+    {
+      // we increase the speed of the blower every 1ms        
+      uiEpapSettingTemp-=2;                           // Slope of 5ms/hPa => 0.2hPa/ms
+      if (uiEpapSettingTemp<uiVentilationSet[PEEP_SET]) 
+        uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
+    } 
+    
+    // Barometric Mode : error computation
+    if (fFirstCycleExpi==FALSE)    
+    {
+      lError=(int32_t)uiEpapSettingTemp-(int32_t)uiProximalPressureMes;
+      lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_E] * lError;   
+    }
+    else    
+    {
+      lError=(int32_t)uiVentilationSet[PEEP_SET]-(int32_t)uiProximalPressureMes;
+      lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_E]>>2) * lError;   
+    }  
+             
+    // Close loop in pressure    
+    if ((lIntegral_Pressure_E>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureE==FALSE)) 
+    {
+      if ((lIntegral_Pressure_E + lIntegralTerm) <0)
+        lIntegral_Pressure_E = INTEGRAL_MAX;
+      else    
+        lIntegral_Pressure_E += lIntegralTerm;       
+    }
+    else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureE==FALSE)) 
+    {
+      if ((lIntegral_Pressure_E + lIntegralTerm)>0)
+        lIntegral_Pressure_E = INTEGRAL_MIN;
+      else
+        lIntegral_Pressure_E += lIntegralTerm;
+    }
+    else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm>=0))
+      lIntegral_Pressure_E += lIntegralTerm;
+    else if ((lIntegral_Pressure_E>=0) && (lIntegralTerm<=0))    
+      lIntegral_Pressure_E += lIntegralTerm;    
+      
+    lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_E] * lError;
+    lOutputPressure = (lIntegral_Pressure_E>>16) + (lPropTerm>>13);
+  
+    // Add constante value (PWM at the end of the previous expiration)    
+    lOutputPressure+=uiPWMatTheEndOfExpiration; 
+           
+    // Flow limiting
+    uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
+    if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)     
+    {  
+      // Impossible to maintain the peep (patient disconnection)
+      if (uiDisconnectionTime==0)
+      {        
+        fBlockCloseLoop=TRUE;                                     // Block the close loop
+        if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
+          uiExpirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
+        else
+          uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+      }
+      else
+        uiDisconnectionTime--;      
+    }   
+    else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
+    {             
+      // Good pressure : no disconnection 
+      uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;                       
+      if (fBlockCloseLoop==TRUE)
+      {
+        // The close loop was block before => unblock it
+        fBlockCloseLoop=FALSE;    
+        lIntegral_Pressure_E=0;
+        bMaxPIOutputPressureE = FALSE;
+        bMinPIOutputPressureE = FALSE;
+        lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
+      }
+      else if (iBlowerFlowSmoothingMes>=0)
+      {
+        // Record current PWM
+        uiMemoPWMDuringDisconnection=uiExpirationBlowerPWMTec;        
+      }
+    }    
+          
+    // Unblock the close loop every 4s in case of none recorded PWM value
+    if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiTeD==0)
+    {
+      uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
+      fBlockCloseLoop=FALSE;
+      lIntegral_Pressure_E=0;
+      bMaxPIOutputPressureE = FALSE;
+      bMinPIOutputPressureE = FALSE;
+      lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
+    }
+        
+    // Update blower PWM
+    if (fBlockCloseLoop==TRUE)
+    {      
+      bMaxPIOutputPressureE = TRUE; 
+    }
+    else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+    {
+      bMaxPIOutputPressureE = TRUE; 
+      uiExpirationBlowerPWMTec=MAX_VOLTAGE_REF;
+    }
+    else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+    {
+      bMinPIOutputPressureE = TRUE; 
+      uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+    else
+    {
+      bMaxPIOutputPressureE = FALSE;
+      bMinPIOutputPressureE = FALSE;
+      uiExpirationBlowerPWMTec = lOutputPressure;
+    }       
+    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                            
+  }
+           
+  // Expiratory time
+  uiTeD++;
+  if (uiTeD>TE_SET_MAX) uiTeD=TE_SET_MAX;
+  if ((uiTeD>=uiTeBaroSet && bPSMode==FALSE) || TestInspiratoryTrigger(bPSMode, uiTeD, uiVentilationSet[TRIG_I_FLOW_SET])==TRUE)
+    {
+    ucVentilationCycle=INSPIRATION_CYCLE;
+    uiTeD=0;         
+      
+    // Record PWM value at the end of the expiration
+    uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;    
+          
+    // Reset PI variables for next inspiration
+    lIntegral_Pressure_I=0;         
+    bMaxPIOutputPressureI=FALSE;
+    bMinPIOutputPressureI=FALSE;
+    }
+  }  
+}
+
+
+
+/*******************************************************************************
+* Function Name  : ManageVolumetricVentilation
+* Description    : Manage Volumetric Ventilation
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ManageVolumetricVentilation(void)
+{
+int32_t   lError;
+int32_t   lPropTerm;                  
+int32_t   lIntegralTerm;
+int32_t   lOutputPressure;
+int16_t   iMaxVtAdjust;
+u16       uiFlowMaxInExpi;
+u16       uiTiMin;
+
+if (ucVentilationCycle==INSPIRATION_CYCLE)
+  {  
+  // ---------------------------------------------------------------------------
+  // -                              INSPIRATION                                -
+  // ---------------------------------------------------------------------------             
+                
+  // Compute Timin
+  if (uiPatientType==PATIENT_ADULT)   
+    uiTiMin=TiVoluSet_A_MIN;
+  else
+    uiTiMin=TiVoluSet_P_MIN;
+  
+  // ************************** Main Blower MANAGEMENT *************************        
+  if (uiTiD==0) 
+  { 
+    // Compute Volume adjustment
+    if (fFirstCycleInspi==FALSE)
+    {
+      if ((uiFlagsAlarm[ALARM_FLAGS1]&HIGH_PRESSURE_ALARM_MASK)==0)
+      {
+        if (ucCounterHPAlarm==0)
+        {
+          iVtAdjust+=(((int16_t)uiVentilationSet[VT_SET]-(int16_t)uiRecordVtiMes>>1));
+          if (iVtAdjust>0)
+          {
+            iMaxVtAdjust=(int16_t)(uiVentilationSet[VT_SET]>>1);        // >0
+            if (iVtAdjust>iMaxVtAdjust)
+              iVtAdjust=iMaxVtAdjust;        
+          }
+          else if (iVtAdjust<0)
+          {
+            iMaxVtAdjust=(int16_t)(~(uiVentilationSet[VT_SET]>>1)+1);  // <0
+            if (iVtAdjust<iMaxVtAdjust)
+              iVtAdjust=iMaxVtAdjust;                
+          }
+        }
+        else
+          ucCounterHPAlarm--;
+      }
+      else
+        ucCounterHPAlarm=1;
+    }
+    else    
+      iVtAdjust=0;   
+    
+    ComputeInspiratoryFlowSetPointInAVC(uiPatientType, (u16)((int16_t)uiVentilationSet[VT_SET]+iVtAdjust), uiVentilationSet[TI_VOLU_SET], uiVentilationSet[SHAPE_SET], &ulMaxIFlowSet, &ulMinIFlowSet, &ulDecFlowStep);    
+  }
+  else
+  {
+    if (ulMaxIFlowSet>=ulDecFlowStep)
+      ulMaxIFlowSet-=ulDecFlowStep;
+    if (ulMaxIFlowSet<ulMinIFlowSet)
+      ulMaxIFlowSet=ulMinIFlowSet;
+  }
+    
+  // Volumetric Mode : error computation
+  //lError=(int32_t)(ulMaxIFlowSet/100)-iBlowerFlowMes;
+  lError=(int32_t)(ulMaxIFlowSet/100)-iBlowerFlowSmoothingMes;
+  if (fFirstCycleInspi==FALSE)
+  {
+    if (ulMaxIFlowSet<150000 && uiTiD>30000)
+      lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_FLOW_I]>>1) * lError;
+    else
+      lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_FLOW_I] * lError;
+  }
+  else
+    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_FLOW_I]>>2) * lError;
+             
+  // Close loop in pressure or flow (PI)
+  if ((lIntegral_Flow_I>=0) && (lIntegralTerm>=0) && (bMaxPIOutputFlowI==FALSE)) 
+    {
+    if ((lIntegral_Flow_I + lIntegralTerm) <0)
+      lIntegral_Flow_I = INTEGRAL_MAX;
+    else    
+      lIntegral_Flow_I += lIntegralTerm;       
+    }
+  else if ((lIntegral_Flow_I<=0) && (lIntegralTerm<=0) && (bMinPIOutputFlowI==FALSE)) 
+    {
+    if ((lIntegral_Flow_I + lIntegralTerm)>0)
+      lIntegral_Flow_I = INTEGRAL_MIN;
+    else
+      lIntegral_Flow_I += lIntegralTerm;
+    }
+  else if ((lIntegral_Flow_I<=0) && (lIntegralTerm>=0))
+    lIntegral_Flow_I += lIntegralTerm;
+  else if ((lIntegral_Flow_I>=0) && (lIntegralTerm<=0))    
+    lIntegral_Flow_I += lIntegralTerm;    
+    
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_FLOW_I] * lError;
+  lOutputPressure = (lIntegral_Flow_I>>16) + (lPropTerm>>13);
+
+  // Add constante value (PWM at the end of the previous inspiration)    
+  lOutputPressure+=uiPWMatTheEndOfExpiration; 
+    
+  if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+    {
+    bMaxPIOutputFlowI = TRUE; 
+    uiInspirationBlowerPWMTec=MAX_VOLTAGE_REF;
+    }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+    {
+    bMinPIOutputFlowI = TRUE; 
+    uiInspirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+  else
+    {
+    bMaxPIOutputFlowI = FALSE;
+    bMinPIOutputFlowI = FALSE;
+    uiInspirationBlowerPWMTec = lOutputPressure;
+    }
+    
+  // Update Blower Speed   
+  SS_Xputdw(mdrv, uiInspirationBlowerPWMTec);                                  
+              
+  // ************************ CYCLE MANAGEMENT *********************************
+  uiTiD++; 
+  if ((uiTiD>=uiVentilationSet[TI_VOLU_SET]) ||
+      (fAlarmPmax==TRUE && uiTiD>uiTiMin))
+    {   
+    // Beginning of the expiration      
+    uiPWMatTheEndOfInspiration=uiInspirationBlowerPWMTec;            
+    uiProximalPressureAtTheEndOfInspiration=uiProximalPressureMes;
+      
+    ucVentilationCycle=EXPIRATION_CYCLE;
+    uiTiD=0;                              
+             
+    // Reset PI variables for next inspiration
+    lIntegral_Pressure_E=0;         
+    bMaxPIOutputPressureE=FALSE;
+    bMinPIOutputPressureE=FALSE;   
+    
+    fFirstCycleExpi=FALSE;  
+    fFirstCycleInspi=FALSE;
+    }
+  }  
+else
+  { 
+  // ---------------------------------------------------------------------------
+  // -                               EXPIRATION                                -
+  // ---------------------------------------------------------------------------                    
+  
+  // *************************** UPDATE SETTINGS *******************************
+  if (ApplyNewVentilationMode()==TRUE)
+    return;
+  
+  // ******************** MAIN BLOWER MANAGEMENT *******************************  
+  if (uiVentilationSet[PEEP_SET]==0)
+  {
+    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
+  }
+  else
+  {
+  if (uiTeD==0) 
+    {         
+    // First blower pressure setting
+    if (uiProximalPressureAtTheEndOfInspiration<uiVentilationSet[PEEP_SET])
+      uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
+    else if (uiProximalPressureAtTheEndOfInspiration>=2)
+      uiEpapSettingTemp=uiProximalPressureAtTheEndOfInspiration-2;  // Slope of 5ms/hPa => 0.2hPa/ms
+    else
+      uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
+    }
+  else 
+    {
+    // we decrease the speed of the blower every 1ms  
+    if (uiEpapSettingTemp>=2)      
+      uiEpapSettingTemp-=2;                           // Slope of 5ms/hPa => 0.2hPa/ms    
+    } 
+    
+  // Pressure set point limitation
+  if (uiEpapSettingTemp<uiVentilationSet[PEEP_SET]) 
+    uiEpapSettingTemp=uiVentilationSet[PEEP_SET];
+  
+  // Barometric Mode : error computation
+  if (fFirstCycleExpi==FALSE)    
+  {
+    lError=(int32_t)uiEpapSettingTemp-(int32_t)uiProximalPressureMes;
+    lIntegralTerm = (int32_t)uiTechnicalDataSet[KI_VENTED_PRESSURE_E] * lError;   
+  }
+  else    
+  {
+    lError=(int32_t)uiVentilationSetTemp[PEEP_SET]-(int32_t)uiProximalPressureMes;
+    lIntegralTerm = (int32_t)(uiTechnicalDataSet[KI_VENTED_PRESSURE_E]>>2) * lError;   
+  }  
+             
+  // Close loop in pressure
+  if ((lIntegral_Pressure_E>=0) && (lIntegralTerm>=0) && (bMaxPIOutputPressureE==FALSE)) 
+  {
+    if ((lIntegral_Pressure_E + lIntegralTerm) <0)
+      lIntegral_Pressure_E = INTEGRAL_MAX;
+    else    
+      lIntegral_Pressure_E += lIntegralTerm;       
+  }
+  else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm<=0) && (bMinPIOutputPressureE==FALSE)) 
+  {
+    if ((lIntegral_Pressure_E + lIntegralTerm)>0)
+      lIntegral_Pressure_E = INTEGRAL_MIN;
+    else
+      lIntegral_Pressure_E += lIntegralTerm;
+  }
+  else if ((lIntegral_Pressure_E<=0) && (lIntegralTerm>=0))
+    lIntegral_Pressure_E += lIntegralTerm;
+  else if ((lIntegral_Pressure_E>=0) && (lIntegralTerm<=0))    
+    lIntegral_Pressure_E += lIntegralTerm;    
+    
+  lPropTerm = (int32_t)uiTechnicalDataSet[KP_VENTED_PRESSURE_E] * lError;
+  lOutputPressure = (lIntegral_Pressure_E>>16) + (lPropTerm>>13);
+
+  // Add constante value (PWM at the end of the previous expiration)    
+  lOutputPressure+=uiPWMatTheEndOfExpiration; 
+  
+  // Flow limiting
+  uiFlowMaxInExpi=uiMaximumFlowInExpiration[uiVentilationSet[PS_CPAP_SET]/10];
+  if (lError>5 && iBlowerFlowSmoothingMes>(int16_t)uiFlowMaxInExpi)     
+  {  
+    // Impossible to maintain the peep (patient disconnection)
+    if (uiDisconnectionTime==0)
+    {        
+      fBlockCloseLoop=TRUE;                                     // Block the close loop
+      if (uiMemoPWMDuringDisconnection!=0)                      // Apply a fixed PWM value
+        uiExpirationBlowerPWMTec=uiMemoPWMDuringDisconnection;
+      else
+        uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+    }
+    else
+      uiDisconnectionTime--;      
+  }   
+  else if (iBlowerFlowSmoothingMes<(int16_t)uiFlowMaxInExpi && (lError>(-2) && lError<2))
+  {             
+    // Good pressure : no disconnection 
+    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;                       
+    if (fBlockCloseLoop==TRUE)
+    {
+      // The close loop was block before => unblock it
+      fBlockCloseLoop=FALSE;    
+      lIntegral_Pressure_E=0;
+      bMaxPIOutputPressureE = FALSE;
+      bMinPIOutputPressureE = FALSE;
+      lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
+    }
+    else if (iBlowerFlowSmoothingMes>=0)
+    {
+      // Record current PWM
+      uiMemoPWMDuringDisconnection=uiExpirationBlowerPWMTec;        
+    }
+  }    
+        
+  // Unblock the close loop every 4s in case of none recorded PWM value
+  if (fBlockCloseLoop==TRUE && uiMemoPWMDuringDisconnection==0 && uiTeD==0)
+  {
+    uiDisconnectionTime=EXPIRATORY_DISCONNECTION_TIME_OUT;
+    fBlockCloseLoop=FALSE;
+    lIntegral_Pressure_E=0;
+    bMaxPIOutputPressureE = FALSE;
+    bMinPIOutputPressureE = FALSE;
+    lOutputPressure=uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
+  }
+  
+  // Update blower PWM
+  if (fBlockCloseLoop==TRUE)
+  {      
+    bMaxPIOutputPressureE = TRUE; 
+  }  
+  else if (lOutputPressure>=((int32_t)MAX_VOLTAGE_REF))
+  {
+    bMaxPIOutputPressureE = TRUE; 
+    uiExpirationBlowerPWMTec=MAX_VOLTAGE_REF;
+  }
+  else if (lOutputPressure<((int32_t)MIN_VOLTAGE_REF))
+  {
+    bMinPIOutputPressureE = TRUE; 
+    uiExpirationBlowerPWMTec=MIN_VOLTAGE_REF;
+  }
+  else
+  {
+    bMaxPIOutputPressureE = FALSE;
+    bMinPIOutputPressureE = FALSE;
+    uiExpirationBlowerPWMTec = lOutputPressure;
+  }    
+  // Update Blower Speed   
+  SS_Xputdw(mdrv, uiExpirationBlowerPWMTec);                
+  }
+  
+  // Expiratory time
+  uiTeD++;
+  if (uiTeD>=uiTeVoluSet || TestInspiratoryTrigger(FALSE, uiTeD, uiVentilationSet[TRIG_I_FLOW_SET])==TRUE)
+    {
+    ucVentilationCycle=INSPIRATION_CYCLE;
+    uiTeD=0;         
+      
+    // Record PWM value at the end of the expiration
+    if (fBlockCloseLoop==FALSE)
+      uiPWMatTheEndOfExpiration=uiExpirationBlowerPWMTec;
+    else
+      uiPWMatTheEndOfExpiration=0;
+    fBlockCloseLoop=FALSE; 
+    
+    // Reset PI variables for next inspiration
+    lIntegral_Flow_I=0;         
+    bMaxPIOutputFlowI=FALSE;
+    bMinPIOutputFlowI=FALSE;
+    }
+  }  
+}
+
+
+
+/*******************************************************************************
+* Function Name  : LaunchTherapyEngine
+* Description    : Select and launch the therapy engine
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void LaunchTherapyEngine(void)
+{
+  if (bMemoStartVentilation==TRUE)
+  {
+    // ---- Check new configuration
+    if (uiTechnicalDataSet[DEVICE_MODE_TEC]!=uiPreviousDeviceMode)
+    {      
+      UpdateSettings();
+      enPreviousMode=NUMBER_OF_MODE;                // Force full init of the variables
+      InitVentilation();  
+      uiPreviousDeviceMode=uiTechnicalDataSet[DEVICE_MODE_TEC];
+    }
+    
+    
+    switch(uiTechnicalDataSet[DEVICE_MODE_TEC])
+    {
+      default:
+      case VENTILATION_MODE:
+      {      
+        if (enVentilationMode==PS_MODE)
+          ManagePACVVentilation(TRUE);
+        else if (enVentilationMode==APCV_MODE)
+          ManagePACVVentilation(FALSE);
+        else if (enVentilationMode==AVC_MODE)
+          ManageVolumetricVentilation();
+        else if (enVentilationMode==CPAP_MODE)
+          ManageCPAPVentilation();             
+        break;
+      }
+      case ONE_CST_PWM_MODE:
+      {      
+        ManageOneCstPWM();             
+        break;
+      }
+      case TWO_CST_PWM_MODE:
+      {      
+        Manage2CstPWM();             
+        break;
+      }
+      case CST_SPEED_MODE:
+      {      
+        ManageCstSpeed();
+        break;
+      }
+      case FLOW_CAL_MODE:
+      {      
+        ManageFlowCalibration();
+        break;
+      }
+      case PRESSURE_CAL_MODE:
+      {      
+        ManagePressureCalibration();
+        break;
+      }
+      case PRESSURE_CST_MODE:
+      {
+        ManageCstPressure();
+        break;
+      }
+    }
+  }
+}
+
+
+/*******************************************************************************
+* Function Name  : StartStopVentilation
+* Description    : Detect a start/stop ventilation request
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void StartStopVentilation(void)
+{
+  #ifndef TEMPERATURE_TRENDS
+  opstatus_t  byOpStatus;  
+  #endif
+      
+  // Check if an alarm must stop the ventilation
+  ucStopVentilationAlarmNumber=ReadStopVentilationAlarmNumber();
+  
+  #ifndef TEMPERATURE_TRENDS  
+  if (uiTechnicalDataSet[START_STOP_VENTILATION]==1 && ucStopVentilationAlarmNumber==SIZE_BLOWER_ALARM)
+  {
+    // *************** VENTILATION is ON **************           
+    if (bMemoStartVentilation==FALSE)
+    {           
+      switch(ucStartVentilationScheduler)
+      {
+        default:
+        case 0:
+        {
+          // Active the HW safety system
+          ControlHW(BLOWER_ON__PAT_CPLD);
+          ucStartVentilationScheduler++;
+          break;
+        }
+        case 1:
+        {
+          // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
+          ControlHW(BLOWER_ON__PAT_CPLD);
+          
+          // Read Offset of the Blower current 
+          ComputeADCBlowerCurrent(TRUE);       
+          
+          ucStartVentilationScheduler++;
+          break;
+        }
+        case 2:
+        {
+          // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
+          ControlHW(BLOWER_ON__PAT_CPLD);
+          
+          // Open motor driver  
+          byOpStatus=SS_Xopen(mdrv);
+          if (byOpStatus==OPSTATUS_FAIL) 
+          {
+            uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_FAILURE_ALARM_MASK;      
+            ucStartVentilationScheduler=0;
+          }
+          else if (byOpStatus==OPSTATUS_OK)
+          {
+            // Force init settings and variables
+            uiPreviousDeviceMode=0xFF;  
+                    
+            uiTempo1min=TEMPO_1MIN;
+            #ifdef  DATA_LOGGING
+              uiTrendsSampleTime=RECORD_TRENDS_SAMPLE_TIME;
+            #endif  // DATA_LOGGING
+            
+            // Check if ventilation mode is activated
+            if (uiTechnicalDataSet[DEVICE_MODE_TEC]!=VENTILATION_MODE)
+              uiFlagsAlarm[ALARM_FLAGS2]|=DEVICE_MODE_ALARM_MASK;
+      
+            bMemoStartVentilation=TRUE;
+            ucStartVentilationScheduler=0;
+          }
+          break;
+        }
+      }
+    }                              
+    // --- Check Safety system for Motor transistors ----
+    else if (IsMotorOK()==FALSE)
+    {
+      ControlHW(BLOWER_OFF__STOP_PAT_CPLD); 
+      uiFlagsAlarm[ALARM_FLAGS2]|=MOTOR_FAILURE_ALARM_MASK;
+    }    
+    // --- Test safety system thanks to the "STOP_BLOWER" Input pin
+    else if (TestStopBlowerInputPin()==OPSTATUS_OK)  
+    {
+      ControlHW(BLOWER_ON__PAT_CPLD); 
+      uiFlagsAlarm[ALARM_FLAGS2]&=(~HW_SAFETY_ALARM_MASK);
+    }
+    else        
+    {
+      uiFlagsAlarm[ALARM_FLAGS2]|=HW_SAFETY_ALARM_MASK;                
+    }
+  }
+  else
+  #endif  // #ifndef TEMPERATURE_TRENDS  
+  {
+    // *************** VENTILATION is OFF **************
+    uiFlagsAlarm[ALARM_FLAGS2]&=(~DEVICE_MODE_ALARM_MASK); 
+    
+    if (ucStopVentilationAlarmNumber!=SIZE_BLOWER_ALARM)
+    {
+      // Stop patting CPLD (WDI_CPLD=0), STOP_BLOWER=0
+      ControlHW(BLOWER_OFF__STOP_PAT_CPLD);             
+    }
+    else 
+    {
+      // Pat CPLD (WDI_CPLD), STOP_BLOWER=1
+      ControlHW(BLOWER_ON__PAT_CPLD);
+        
+      // ---- Test STOP_ACTUATOR Input pin Status
+      if (TestStopBlowerInputPin()==OPSTATUS_FAIL)      
+        uiFlagsAlarm[ALARM_FLAGS2]|=HW_SAFETY_ALARM_MASK; 
+      else
+        uiFlagsAlarm[ALARM_FLAGS2]&=(~HW_SAFETY_ALARM_MASK);
+    }
+    
+    if (bMemoStartVentilation==TRUE)
+    {
+      StopAllActuators();        
+      ClearAllVentilationAlarms();
+      ClearAllMeasures();
+    } 
+    
+    uiTechnicalDataSet[START_STOP_VENTILATION]=0;   
+    bMemoStartVentilation=FALSE;
+    #ifndef TEMPERATURE_TRENDS
+    ucStartVentilationScheduler=0;  
+    #endif
+    bDisableMaroubraCommCommunication=FALSE;
+  }  
+}
+#endif    // #ifndef C_M3_DEVICETEST_TARGET 
+
+
+/*******************************************************************************
+* Function Name  : ComputeTe
+* Description    : Compute expiratory time
+* Input          : uiF  = Breath frequency (bpm) 
+                   uiTi =  Inspiratory time (ms)
+* Output         : Expiratory time (ms)
+* Return         : None
+*******************************************************************************/
+#ifndef C_M3_DEVICETEST_TARGET 
+u16 ComputeTe(u16 uiF, u16 uiTi)
+{
+  u16 uiTtot;
+  u16 uiTeTemp=TE_SET_MIN;
+  
+  if (uiF!=0)
+  {
+    // Compute Ttotal
+    uiTtot=60000/uiF;
+    if (uiTtot>uiTi)
+    {
+      uiTeTemp=uiTtot-uiTi;
+      if (uiTeTemp<TE_SET_MIN)
+        uiTeTemp=TE_SET_MIN;      
+    }
+  }
+  else
+  {
+    // F=0 => Te=2xTi
+    uiTeTemp=uiTi<<1;
+  }            
+  return(uiTeTemp);
+}
+
+
+/*******************************************************************************
+* Function Name  : UpdateSettings
+* Description    : Update the settings zone with the temporary settings zone
+* Input          : None
+* Output         : None
+* Return         : TRUE if the ventilation mode has changed
+*******************************************************************************/
+bool UpdateSettings(void)
+{
+  u8  ucIndex;
+  
+  // Take into account a modification of the PEEP
+  if (uiVentilationSet[PEEP_SET]!=uiVentilationSetTemp[PEEP_SET] || uiVentilationSet[PS_CPAP_SET]!=uiVentilationSetTemp[PS_CPAP_SET])
+    uiMemoPWMDuringDisconnection=0;
+  
+  // Transfert data from the setting temporary zone to the settings zone    
+  for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)      
+    uiVentilationSet[ucIndex]=uiVentilationSetTemp[ucIndex];  
+  
+  // Update barometric expiratory time  
+  uiTeBaroSet=ComputeTe(uiVentilationSet[BREATH_RATE_BARO_SET], uiVentilationSet[TI_BARO_SET]);  
+  
+  // Update volumetric expiratory time
+  uiTeVoluSet=ComputeTe(uiVentilationSet[BREATH_RATE_VOLU_SET], uiVentilationSet[TI_VOLU_SET]);
+  
+  // Update Tube configuration type
+  enTubeConfigType=enTubeConfigTypeTemp;
+  
+  // Update Patient type
+  uiPatientType=uiPatientTypeTemp;
+  
+  // Update Ventilation mode
+  if (enVentilationMode!=enVentilationModeTemp)
+  {
+    enVentilationMode=enVentilationModeTemp;
+    InitVentilation();      
+    return(TRUE);
+  }  
+  return(FALSE);
+}
+
+
+/*******************************************************************************
+* Function Name  : ApplyNewVentilationMode
+* Description    : Update settings and init variables if the ventilation mode has changed
+* Input          : None
+* Output         : None
+* Return         : TRUE if new ventilation mode is applied
+*******************************************************************************/
+bool ApplyNewVentilationMode(void)
+{
+  if (fUpdateTheSettings==TRUE)
+  {
+      fUpdateTheSettings=FALSE;
+      if (UpdateSettings()==TRUE)
+      {
+        InitVentilation();
+        return(TRUE);
+      }
+  }
+  return(FALSE);
+}
+
+
+/*******************************************************************************
+* Function Name  : ComputeInspiratoryFlowSetPointInAVC
+* Description    : Compute:
+                      - the inspiratory flow max set point
+                      - the inspiratory flow min set point
+                      - the flow step between the flow max and the flow min during Ti
+* Input          : uiTypeOfPatient = Adult or Pedia
+                   uiVtc        = set point in volume (ml)
+                   uiTi         = Ti set point (ms)
+                   uiFlowShape  = Flow shape (0 to 4)
+* Output         : uiMaxFlow    = the inspiratory flow max set point (cl/min => 100=1l/min)
+                   uiMinFlow    = the inspiratory flow min set point (cl/min => 100=1l/min)
+                   uiFlowStep   = the flow step between the flow max and the flow min during Ti (cl/min => 100=1l/min)
+* Return         : None
+*******************************************************************************/
+void ComputeInspiratoryFlowSetPointInAVC(u16 uiTypeOfPatient, u16 uiVtc, u16 uiTi, u16 uiFlowShape, u32 *ulMaxFlow, u32 *ulMinFlow, u32 *ulFlowStep)
+{
+  u32	  ulFlowMax;
+  u32	  ulFlowMin;
+  u32     ulMaxMaxFlow;
+  u32     ulMinMinFlow;
+  u16     uiTiMin;
+  u32     ulFlowStepTemp;
+  
+  // Define min/max flow
+  if (uiTypeOfPatient==PATIENT_ADULT)
+  {
+    ulMinMinFlow=InspiratoryFlowSet_A_MIN;
+    ulMaxMaxFlow=InspiratoryFlowSet_A_MAX;
+    uiTiMin=TiVoluSet_A_MIN;
+  }
+  else
+  {
+    ulMinMinFlow=InspiratoryFlowSet_P_MIN;
+    ulMaxMaxFlow=InspiratoryFlowSet_P_MAX;
+    uiTiMin=TiVoluSet_P_MIN;
+  }
+  
+  // Check Ti
+  if (uiTi==0)
+    uiTi=uiTiMin;
+  
+  // Compute flow max
+  switch(uiFlowShape)
+  {
+    default:
+    case 0:
+    {
+      ulFlowMax=((u32)uiVtc*6000)/uiTi;
+      break;
+    }
+    case 1:
+    {
+      ulFlowMax=((u32)uiVtc*7500)/uiTi;
+      break;
+    }
+    case 2:
+    {
+      ulFlowMax=((u32)uiVtc*9000)/uiTi;
+      break;
+    }
+    case 3:
+    {
+      ulFlowMax=((u32)uiVtc*10500)/uiTi;
+      break;
+    }
+    case 4:
+    {
+      ulFlowMax=((u32)uiVtc*12000)/uiTi;
+      break;
+    }
+  }
+  
+  // Limitation of the max flow
+  if (ulFlowMax>ulMaxMaxFlow)
+    ulFlowMax=ulMaxMaxFlow;
+  
+  // Limitation of the min flow
+  if (ulFlowMax<ulMinMinFlow)
+    ulFlowMax=ulMinMinFlow;
+    
+  // Factor 100 on flow max (and flow min and flow step)  
+  ulFlowMax*=100;
+  
+  // Compute flow min and flow step
+  switch(uiFlowShape)
+  {
+    default:
+    case 0:
+    {
+      ulFlowMin=ulFlowMax;
+      break;
+    }
+    case 1:
+    {
+      ulFlowMin=(ulFlowMax*3)>>2;
+      break;
+    }
+    case 2:
+    {
+      ulFlowMin=ulFlowMax>>1;
+      break;
+    }
+    case 3:
+    {
+      ulFlowMin=ulFlowMax>>2;
+      break;
+    }
+    case 4:
+    {
+      ulFlowMin=0;
+      break;
+    }
+  }
+        
+  // Max flow
+  *ulMaxFlow=ulFlowMax;
+  
+  // Min flow
+  *ulMinFlow=ulFlowMin;
+  
+  // Flow Step  
+  ulFlowStepTemp=(ulFlowMax-ulFlowMin)/uiTi;
+  //if (uiFlowStepTemp==0 && uiFlowShape!=0) uiFlowStepTemp=1;
+  *ulFlowStep=ulFlowStepTemp;
+}
+
+
+
+/*******************************************************************************
+* Function Name  : TestTriggerExpiratoire
+* Description    : Manage the expiratory trigger
+* Input          : ucValeurSeuil = threshold (% of the flow max) to reach in order to cycle
+* Output         : None
+* Return         : TRUE if cycling active
+*******************************************************************************/
+unsigned char TestTriggerExpiratoire(unsigned char ucValeurSeuil, unsigned int uiPressureSetting)
+{
+  unsigned char  ucSeuil=ucValeurSeuil;
+  unsigned int   uiCalculTemp;
+  int16_t iConductanceBaseLine=UpdateInspiratoryConductanceAverage();
+  // Management automatic expiratory trigger
+  ucTempoTriggerExpiAuto--;
+  if (ucTempoTriggerExpiAuto==0)
+  {
+    ucTempoTriggerExpiAuto=TEMPO_TRIGGER_EXPI;
+    ucExpiTriggerTreshold++;
+  }
+  
+  // Test si flow<0??
+  if (iBlowerFlowSmoothingMes<0)
+  {
+    return(TRUE);  
+  }
+  // Test if deacring flow??
+  else if (iBlowerFlowSmoothingMes<iBlowerFlowSmoothingMaxMes)
+  {
+    // Test if Trigger Expi=AUTO ??
+    if ((ucValeurSeuil==ExpiTriggerSet_A_MAX && uiPatientType==PATIENT_ADULT) ||
+        (ucValeurSeuil==ExpiTriggerSet_P_MAX && uiPatientType==PATIENT_PEDIA))
+      ucSeuil=ucExpiTriggerTreshold;
+     
+    u16 conducThresh = 2000;
+    
+    if(enTubeConfigType == 1 )
+      conducThresh = 750;
+    else if(enTubeConfigType == 2)
+      conducThresh = 1500;
+      
+    // Test if cycling or not
+    uiCalculTemp=((unsigned long)iBlowerFlowSmoothingMaxMes*ucSeuil)/100;
+    if (uiCalculTemp>iBlowerFlowSmoothingMes)
+      return(TRUE);  
+    else if (uiProximalPressureMes>(uiPressureSetting+20))
+      return(TRUE);
+    else if (uiConductanceCalc < (iConductanceBaseLine - conducThresh))
+    {
+      ResetInspiratoryConductanceAverage();
+      return(TRUE); 
+    }
+  }
+  return(FALSE);
+}
+
+
+/*******************************************************************************
+* Function Name  : TestInspiratoryTrigger
+* Description    : Manage the inspiratory trigger
+* Input          : bSpont = TRUE if spontaneous mode
+*                  uiTe = expiration time (ms)
+*                  uiFlowTreshold = flow threshold (dl/min)
+* Output         : None
+* Return         : TRUE if cycling active
+*******************************************************************************/
+bool  TestInspiratoryTrigger(bool bSpont, u16 uiTe, u16 uiFlowTreshold)
+{  
+  //int16_t   iInspiratoryFlowDeltaAverage;
+  //int16_t   iDeltaOfTheDelta1, iDeltaOfTheDelta2, iDeltaOfTheDelta3, iDeltaOfTheDelta4;  
+  bool      bTrigger=FALSE;
+  //int16_t   iVirtualFlow;
+  int16_t   iConductanceBaseLine;
+  
+  // Manual breath management
+  if (uiTe>TE_SET_MIN)
+  {
+    if (bManualBreath==TRUE)
+    {
+      bManualBreath=FALSE;
+      bDisplayInspiratoryTrigger=TRUE;
+      return(TRUE);
+    }    
+  }
+  
+  // Trigger management
+  if ((bSpont==TRUE) || 
+      (bSpont==FALSE && uiFlowTreshold<InspiTriggerFlowSet_A_MAX && uiPatientType==PATIENT_ADULT) ||
+      (bSpont==FALSE && uiFlowTreshold<InspiTriggerFlowSet_P_MAX && uiPatientType==PATIENT_PEDIA))        
+  {
+    // Init scheduler
+    if (uiTe==1)
+    {
+      ucInspiTriggerScheduler=0;
+      iInspiratoryFlowMin=0;
+      ucMinFlowCounter=NUMBER_MIN_FLOW_VALUE;
+      ucCounterTriggerValid=NUMBER_TRIGGER_VALID;
+      bDetectionConstantFlow=FALSE;
+    }
+    
+    iConductanceBaseLine=UpdateInspiratoryConductanceAverage();
+    // Manage detection phase
+    switch(ucInspiTriggerScheduler)
+    {
+      default:
+      case 0:
+      {    
+        // Update the buffer on the Inspiratory flow average
+        
+        // Detect min flow
+        if (iBlowerFlowSmoothingMesForTrigger<iInspiratoryFlowMin)
+        {
+          iInspiratoryFlowMin=iBlowerFlowSmoothingMesForTrigger;
+          ucMinFlowCounter=NUMBER_MIN_FLOW_VALUE;
+        }
+        else
+        {
+          ucMinFlowCounter--;
+          if (ucMinFlowCounter==0)
+            ucInspiTriggerScheduler=1;
+        }        
+        break;
+      }            
+      case 1:
+      {    
+        //ucTriggerNumber=0;
+               
+        if (uiTe>TE_SET_MIN)
+        {
+//          // Fast trigger management
+//          if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50]<=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-25])
+//          {
+//            iVirtualFlow=(iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-25]<<1)-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50];                  
+//            if (iBlowerFlowSmoothingMesForTrigger>=(iVirtualFlow+(int16_t)(uiFlowTreshold*7)))
+//            {
+//              //ucTriggerNumber=1;
+//              //if (fBlockCloseLoop==FALSE)
+//                bTrigger=TRUE;    
+//            }
+//          }          
+//          if (bTrigger==FALSE && iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-100]<=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50])
+//          {
+//            iVirtualFlow=(iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-50]<<1)-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-100];
+//            if (iBlowerFlowSmoothingMesForTrigger>=(iVirtualFlow+(int16_t)(uiFlowTreshold*15)))
+//            {
+//              //ucTriggerNumber=2;
+//              //if (fBlockCloseLoop==FALSE)
+//                bTrigger=TRUE;            
+//            }
+//          }
+//                    
+//          // Slow trigger management
+//          if (TestInspiratorySlowTrigger(iFlowBaseLine, uiFlowTreshold*10)==TRUE)
+//          {
+//            //ucTriggerNumber=3;
+//            bTrigger=TRUE;
+//          }                    
+             //Conductance Trigger
+          if(uiConductanceCalc >= (iConductanceBaseLine + 2000))
+          {
+            bTrigger = TRUE;            
+          }
+        
+          // Trigger occurs??
+          if (bTrigger==TRUE)
+          {
+            ucCounterTriggerValid--;
+            if (ucCounterTriggerValid==0) 
+            {
+              bDisplayInspiratoryTrigger=TRUE;
+              ResetInspiratoryConductanceAverage();
+              return(TRUE);            
+            }
+          }        
+          else          
+            ucCounterTriggerValid=NUMBER_TRIGGER_VALID;          
+        }
+        break;
+      }
+    }
+  }
+  return(FALSE);
+}
+        
+/*******************************************************************************
+* Function Name  : UpdateInspiratoryConductanceAverage
+* Description    : Fill the buffer with the expiratory conductance and compute the average
+* Input          : None
+* Output         : None
+* Return         : Inspiratory flow average
+*******************************************************************************/        
+u16         conducIndex = 0;
+int32_t     lSumConductance = 0;
+bool bufFilled = FALSE;
+  
+int16_t UpdateInspiratoryConductanceAverage(void)
+{
+  int16_t oldValue = iBufferIFlow[conducIndex];
+  iBufferIFlow[conducIndex] = uiConductanceCalc;
+  lSumConductance += uiConductanceCalc;
+  conducIndex++;
+  
+  if(conducIndex > SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER)
+  {
+    conducIndex = 0;
+    bufFilled = TRUE;
+  }
+  
+  if(bufFilled)
+  {
+    lSumConductance -= oldValue;
+    return (lSumConductance/SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER); 
+  }
+  else
+  {
+    return (lSumConductance/conducIndex); 
+  }
+}
+
+/*******************************************************************************
+* Function Name  : ResetInspiratoryConductanceAverage
+* Description    : Fill the buffer with the expiratory conductance and compute the average
+* Input          : None
+* Output         : None
+* Return         : Inspiratory flow average
+*******************************************************************************/        
+  
+void ResetInspiratoryConductanceAverage(void)
+{
+  conducIndex = 0;
+  lSumConductance = 0;
+  bufFilled = FALSE;
+}
+
+/*******************************************************************************
+* Function Name  : UpdateInspiratoryFlowAverage
+* Description    : Fill the buffer with the inspiratory flow and compute the average
+* Input          : None
+* Output         : None
+* Return         : Inspiratory flow average
+*******************************************************************************/        
+int16_t UpdateInspiratoryFlowAverage(void)
+{
+  u16         uiIndex;
+  int32_t     lSumIFlow=0;
+  
+  // Roll the buffer
+  for(uiIndex=1; uiIndex<SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER; uiIndex++)
+  {
+    iBufferIFlow[uiIndex-1]=iBufferIFlow[uiIndex];                    // Upate the Inspiratory Flow buffer
+    lSumIFlow+=iBufferIFlow[uiIndex-1];                               // Sum the Inspiratory Flow
+  }
+    
+  // Add new flow value
+  iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]=iBlowerFlowSmoothingMesForTrigger;   // Upate the Inspiratory Flow buffer
+  lSumIFlow+=iBlowerFlowSmoothingMesForTrigger;                                           // Sum the Inspiratory Flow     
+  
+  return(lSumIFlow/SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER); 
+}        
+
+
+/*******************************************************************************
+* Function Name  : TestInspiratorySlowTrigger
+* Description    : Compute flow base line and test trigger
+* Input          : FlowTreshold = flow threshold (cl/min)
+* Output         : None
+* Return         : TRUE if trigger occurs
+*******************************************************************************/        
+bool TestInspiratorySlowTrigger(int16_t iTheFlowBaseLine, u16 uiFlowTreshold)
+{
+  int16_t   iFlowDelta1, iFlowDelta2, iFlowDelta3;
+  
+  if (bDetectionConstantFlow==FALSE)
+  {
+    // Detection constant flow
+    if (iBufferIFlow[0]<iTheFlowBaseLine)
+      iFlowDelta1=iTheFlowBaseLine-iBufferIFlow[0];
+    else
+      iFlowDelta1=iBufferIFlow[0]-iTheFlowBaseLine;
+    
+    if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1]<iTheFlowBaseLine)
+      iFlowDelta2=iTheFlowBaseLine-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1];
+    else
+      iFlowDelta2=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER>>1]-iTheFlowBaseLine;
+    
+    if (iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]<iTheFlowBaseLine)
+      iFlowDelta3=iTheFlowBaseLine-iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1];
+    else
+      iFlowDelta3=iBufferIFlow[SIZE_INSPIRATORY_FLOW_AVERAGE_BUFFER-1]-iTheFlowBaseLine;
+    
+    if (iFlowDelta1<60 && iFlowDelta2<60 && iFlowDelta3<60)
+    {
+      iFlowBaseLineReference=iTheFlowBaseLine;
+      bDetectionConstantFlow=TRUE;
+    }
+  }
+  else
+  {
+    // Detect trigger
+    if (iBlowerFlowSmoothingMesForTrigger>=(iFlowBaseLineReference+(int16_t)uiFlowTreshold))
+    {
+      return(TRUE);
+    }
+  }
+  return(FALSE);
+}
+
+
+/*******************************************************************************
+* Function Name  : ApplyDefaultValueToTemporaryVentilationSettings
+* Description    : Init temporary ventilation settings with default values
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/        
+void ApplyDefaultValueToTemporaryVentilationSettings(void)
+{
+  u8  ucIndex;
+  
+  enVentilationModeTemp=VentilationMode_DEF;          
+  uiPatientTypeTemp=PatientType_DEF; 
+  enTubeConfigTypeTemp=(enMaroubraTubeConfigurationList)ReturnDefaultTubeConfiguration(VentilationMode_DEF);
+  
+  // Init all temporary settings
+  if (uiPatientType==PATIENT_ADULT)
+  {
+    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
+      uiVentilationSetTemp[ucIndex]=sLRSGroup[ucIndex].uiDefault_Adult;
+  }
+  else
+  {
+    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
+      uiVentilationSetTemp[ucIndex]=sLRSGroup[ucIndex].uiDefault_Pedia;
+  }
+}
+
+
+/*******************************************************************************
+* Function Name  : CheckTemporaryVentilationSettingRange
+* Description    : Check all the temporary settings range
+* Input          : None
+* Output         : None
+* Return         : FALSE if one the settings is out of range
+*******************************************************************************/
+opstatus_t CheckTemporaryVentilationSettingRange(void)
+{
+  u8  ucIndex;
+  
+  if ((uiPatientTypeTemp==PATIENT_PEDIA || uiPatientTypeTemp==PATIENT_ADULT) && enVentilationModeTemp<NUMBER_OF_MODE && enTubeConfigTypeTemp<NUMBER_OF_TUBE_CONFIGURATION)
+  {   
+    for (ucIndex=0; ucIndex<SIZE_LRS_GROUP; ucIndex++)
+    {
+      // Check data range
+      if (uiPatientTypeTemp==PATIENT_PEDIA)
+      {
+        if (uiVentilationSetTemp[ucIndex]<sLRSGroup[ucIndex].uiMin_Pedia)
+          return(OPSTATUS_FAIL);
+        else if (uiVentilationSetTemp[ucIndex]>sLRSGroup[ucIndex].uiMax_Pedia)
+          return(OPSTATUS_FAIL);
+      }
+      else
+      {
+        if (uiVentilationSetTemp[ucIndex]<sLRSGroup[ucIndex].uiMin_Adult)
+          return(OPSTATUS_FAIL);
+        else if (uiVentilationSetTemp[ucIndex]>sLRSGroup[ucIndex].uiMax_Adult)
+          return(OPSTATUS_FAIL);
+      }
+    }
+    return(OPSTATUS_OK);
+  }
+  return(OPSTATUS_FAIL);
+}
+
+
+
+/*******************************************************************************
+* Function Name  : ApplyDefaultValueToTechnicalSettings
+* Description    : Init technical settings with default values
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/        
+void ApplyDefaultValueToTechnicalSettings(void)
+{
+  u8  ucIndex;
+  
+  // Init all temporary settings
+  for (ucIndex=0; ucIndex<SIZE_LRTS_GROUP; ucIndex++)
+    uiTechnicalDataSet[ucIndex]=sLRTSGroup[ucIndex].uiDefault;
+}
+
+
+/*******************************************************************************
+* Function Name  : CheckTechnicalSettingsRange
+* Description    : Check all the technical settings range
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void CheckTechnicalSettingsRange(void)
+{
+  u8    ucIndex;
+  bool  fError=FALSE;
+  
+  for (ucIndex=0; ucIndex<SIZE_LRTS_GROUP; ucIndex++)
+  {
+    if (uiTechnicalDataSet[ucIndex]<sLRTSGroup[ucIndex].uiMin || uiTechnicalDataSet[ucIndex]>sLRTSGroup[ucIndex].uiMax)
+    {
+      uiTechnicalDataSet[ucIndex]=sLRTSGroup[ucIndex].uiDefault;
+      fError=TRUE;
+      //break;
+    }
+  }
+  
+  if (fError==TRUE)
+    uiFlagsAlarm[ALARM_FLAGS2]|=TECHNICAL_SETTINGS_RANGE_ALARM_MASK;
+  else
+    uiFlagsAlarm[ALARM_FLAGS2]&=(~TECHNICAL_SETTINGS_RANGE_ALARM_MASK);
+}
+
+
+/*******************************************************************************
+* Function Name  : CheckFlowLUTRange
+* Description    : Check the flow LUT
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void CheckFlowLUTRange(void)
+{
+  u16   uiIndex;
+  bool  fError=FALSE;
+  
+  if (stLUTFlowSensor.uiLUT_TableSize<(FLOW_CALIB_NUMBER_OF_SAMPLES>>1) || stLUTFlowSensor.uiLUT_TableSize>FLOW_CALIB_NUMBER_OF_SAMPLES)
+  {
+    ApplyDefaultFlowLUT();
+    fError=TRUE;
+  }
+  else
+  {
+    for (uiIndex=1; uiIndex<stLUTFlowSensor.uiLUT_TableSize; uiIndex++)
+    {
+      if (stLUTFlowSensor.uiFlowValue[uiIndex]<=stLUTFlowSensor.uiFlowValue[uiIndex-1]  || 
+          stLUTFlowSensor.uiFlowSensorTicks[uiIndex]<=stLUTFlowSensor.uiFlowSensorTicks[uiIndex-1])
+      {
+        ApplyDefaultFlowLUT();
+        fError=TRUE;
+        break;
+      }
+    }
+  }
+  
+  if (fError==TRUE)
+    uiFlagsAlarm[ALARM_FLAGS2]|=NO_FLOW_LUT_ALARM_MASK;
+  else
+    uiFlagsAlarm[ALARM_FLAGS2]&=(~NO_FLOW_LUT_ALARM_MASK);
+}
+
+
+/*******************************************************************************
+* Function Name  : ApplyDefaultFlowLUT
+* Description    : Apply default value for the flow LUT
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ApplyDefaultFlowLUT(void)
+{
+  u16   uiIndex;
+  
+  stLUTFlowSensor.uiLUT_TableSize=stDefaultLUTFlowSensor.uiLUT_TableSize;
+  for (uiIndex=0; uiIndex<FLOW_CALIB_NUMBER_OF_SAMPLES; uiIndex++)
+  {
+    stLUTFlowSensor.uiFlowValue[uiIndex]=stDefaultLUTFlowSensor.uiFlowValue[uiIndex];
+    stLUTFlowSensor.uiFlowSensorTicks[uiIndex]=stDefaultLUTFlowSensor.uiFlowSensorTicks[uiIndex];
+  }
+}
+
+
+/*******************************************************************************
+* Function Name  : ReturnDefaultTubeConfiguration
+* Description    : The default tubing configuration according to the current ventilation mode
+* Input          : a ventilation mode
+* Output         : None
+* Return         : The tube configuration
+*******************************************************************************/
+u16 ReturnDefaultTubeConfiguration(u16 uiMode)
+{
+  u8  ucIndex;
+  
+  for (ucIndex=0; ucIndex<NUMBER_OF_TUBE_CONFIGURATION; ucIndex++)
+  {
+    if (ucTubeConfigurationTable[ucIndex][uiMode]==TUBE_DEFAULT)
+    {
+      return(ucIndex);
+    }
+  }
+  return(0);
+}
+
+
+/*******************************************************************************
+* Function Name  : ApplyAllDefaultValues
+* Description    : Apply all default values in the technical and settings zones
+*                : BE CARFUL this function call "ControlHW" function
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void ApplyAllDefaultValues(void)
+{ 
+  // Init ventilation settings
+  ApplyDefaultValueToTemporaryVentilationSettings();
+    
+  // Init technical settings
+  ApplyDefaultValueToTechnicalSettings();
+  
+  // Init flow LUT
+  ApplyDefaultFlowLUT();
+  
+  // Default value for the device/patient time counter
+  ulDeviceTimeCounter=0;
+  ulPatientTimeCounter=0;
+        
+  // Default value for the blower revolution counter
+  ulBlowerRevolutionCounter=0;
+  
+  bComputeOffsetSensors=TRUE;
+}
+#endif  // C_M3_DEVICETEST_TARGET 
+
+/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
+
+
+
--- a/main.cpp	Tue Jun 09 22:57:20 2020 +0000
+++ b/main.cpp	Thu Jun 11 22:55:06 2020 +0000
@@ -1,167 +1,46 @@
 #include "mbed.h"
 #include "TS_DISCO_F429ZI.h"
 #include "LCD_DISCO_F429ZI.h"
+#include "Screens.h"
+#include "Touch.h"
+#include "main.h"
 
 #define y_max 310
 DigitalOut led1(LED1);
+
 Ticker ts_service;
-
 AnalogIn   pdiff(PC_5);
 AnalogIn   p_guage(PC_4);
 
 LCD_DISCO_F429ZI lcd;
 TS_DISCO_F429ZI ts;
+
 //PwmOut led(LED1);
 PwmOut motor(PB_0);
 
-TS_StateTypeDef TS_State;
-TS_StateTypeDef Old_TS_State;
+
 
 uint8_t text[30];
-uint8_t status;
-
-uint16_t x, y = 0;
-uint16_t touch_x, touch_y = 0;
-bool press_detected = false;
 
 uint16_t setPressure = 0;
-uint8_t isr_text[30];
-uint8_t display_screen = 1;
-
-int showScreen(uint8_t screen)
-{
-    switch(screen) 
-    {
-        case 1 :
-            BSP_LCD_SetFont(&Font20);
-            setPressure = (y*20)/y_max;
-            sprintf((char*)isr_text, "SetP=%2d", setPressure);   
-            lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&isr_text, CENTER_MODE);
-            sprintf((char*)isr_text, "PDIFF=%.2f", (pdiff.read()*6.0f)-0.8f);
-            lcd.DisplayStringAt(0, LINE(2), (uint8_t *)&isr_text, CENTER_MODE);
-            sprintf((char*)isr_text, "PGUAGE=%.2f", (p_guage.read()*38.0f)-10.0f);
-            lcd.DisplayStringAt(0, LINE(3), (uint8_t *)&isr_text, CENTER_MODE);
-            
-            BSP_LCD_SetFont(&Font12);
-            lcd.DrawRect(5, 100, 70, 50);
-            lcd.DrawRect(85, 100, 70, 50);
-            lcd.DrawRect(165, 100, 70, 50);
-            sprintf((char*)isr_text, "  Start");   
-            lcd.DisplayStringAt(10, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            sprintf((char*)isr_text, "Settings");   
-            lcd.DisplayStringAt(95, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            sprintf((char*)isr_text, "Stop");   
-            lcd.DisplayStringAt(170, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            
-            lcd.DrawRect(5, 160, 70, 50);
-            lcd.DrawRect(85, 160, 70, 50);
-            lcd.DrawRect(165, 160, 70, 50);            
-            
-            lcd.DrawRect(5, 220, 70, 50);
-            lcd.DrawRect(85, 220, 70, 50);
-            lcd.DrawRect(165, 220, 70, 50);
-            break;
-        case 2 :
-            BSP_LCD_SetFont(&Font20);
-            setPressure = (y*20)/y_max;
-            sprintf((char*)isr_text, "SetPress=%2d", setPressure);   
-            lcd.DisplayStringAt(0, LINE(1), (uint8_t *)&isr_text, CENTER_MODE);
-            sprintf((char*)isr_text, "PDIFF=%.2f", pdiff.read()*6.0f);
-            lcd.DisplayStringAt(0, LINE(2), (uint8_t *)&isr_text, CENTER_MODE);
-            sprintf((char*)isr_text, "PGUAGE=%.2f", p_guage.read()*38.0f);
-            lcd.DisplayStringAt(0, LINE(3), (uint8_t *)&isr_text, CENTER_MODE);
-            
-            BSP_LCD_SetFont(&Font12);
-            lcd.DrawRect(5, 100, 70, 50);
-            lcd.DrawRect(85, 100, 70, 50);
-            lcd.DrawRect(165, 100, 70, 50);
-            sprintf((char*)isr_text, "  Start");   
-            lcd.DisplayStringAt(10, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            sprintf((char*)isr_text, "Settings");   
-            lcd.DisplayStringAt(95, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            sprintf((char*)isr_text, "  Stop");   
-            lcd.DisplayStringAt(165, 130, (uint8_t *)&isr_text, LEFT_MODE);
-            
-            lcd.DrawRect(5, 160, 70, 50);
-            lcd.DrawRect(85, 160, 70, 50);
-            lcd.DrawRect(165, 160, 70, 50);            
-            
-            lcd.DrawRect(5, 220, 70, 50);
-            lcd.DrawRect(85, 220, 70, 50);
-            lcd.DrawRect(165, 220, 70, 50);
-    }
-    return screen;
-}
-
-void CheckPress()
-{
-    if(press_detected)
-    {
-        display_screen = 2;
-    }
-    
-}
-
-void CheckTs()
-{
-    ts.GetState(&TS_State);      
-    if (TS_State.TouchDetected)
-    {
-        x = TS_State.X;
-        y = TS_State.Y;
-    }
-    if ((Old_TS_State.TouchDetected) && (!TS_State.TouchDetected))
-    {
-     touch_x = x;
-     touch_y = y;
-     press_detected = true;
-    }   
-    Old_TS_State = TS_State;
-}
+ScreenState display_screen = StartUp; // StartScreen 
+uint8_t status = 0;
 
 int main()
 {
     motor.period(0.1f);
-    
-    BSP_LCD_SetFont(&Font20);
-  
-    lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN", CENTER_MODE);
-    lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"DEMO", CENTER_MODE);
-    
-     
+       
+    ts_service.attach(&CheckTs, 0.1); // the address of the function to be attached (flip) and the interval (2 seconds)  
+    status= ts.Init(lcd.GetXSize(), lcd.GetYSize());
+      
     wait(1);
-  
-    status = ts.Init(lcd.GetXSize(), lcd.GetYSize());
-  
-    if (status != TS_OK)
-    {
-      lcd.Clear(LCD_COLOR_RED);
-      lcd.SetBackColor(LCD_COLOR_RED);
-      lcd.SetTextColor(LCD_COLOR_WHITE);
-      lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN", CENTER_MODE);
-      lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"INIT FAIL", CENTER_MODE);
-    }
-    else
-    {
-      lcd.Clear(LCD_COLOR_GREEN);
-      lcd.SetBackColor(LCD_COLOR_GREEN);
-      lcd.SetTextColor(LCD_COLOR_WHITE);
-      lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN", CENTER_MODE);
-      lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"INIT OK", CENTER_MODE);
-    }
-    
-    wait(1);
-    lcd.Clear(LCD_COLOR_BLUE);
-    lcd.SetBackColor(LCD_COLOR_BLUE);
+    lcd.Clear(LCD_COLOR_DARKGRAY);
+    lcd.SetBackColor(LCD_COLOR_DARKGRAY);
     lcd.SetTextColor(LCD_COLOR_WHITE);
-    
-    ts_service.attach(&CheckTs, 0.2); // the address of the function to be attached (flip) and the interval (2 seconds)
   
     while(1)
     {
-      led1 = !led1;
-      wait(0.2);
-      CheckPress();
-      showScreen(display_screen);
+      CheckPress(display_screen);
+      showScreen(display_screen,lcd);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Thu Jun 11 22:55:06 2020 +0000
@@ -0,0 +1,18 @@
+#ifndef __MAIN_H
+#define __MAIN_H
+#ifdef TARGET_DISCO_F429ZI
+#include "TS_DISCO_F429ZI.h"
+#include "LCD_DISCO_F429ZI.h"
+#include "Screens.h"
+
+/*******************************Variables**************************/
+extern ScreenState display_screen; // Screen State Variable
+extern uint16_t setPressure ;  // Pressure Setting
+extern Ticker ts_service;
+extern TS_DISCO_F429ZI ts;
+
+#else
+#error "This class must be used with DISCO_F429ZI board only."
+#endif // TARGET_DISCO_F429ZI
+
+#endif   
\ No newline at end of file