![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Started a gui menuflow
Dependencies: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI BSP_DISCO_F429ZI
Monitoring.txt
- Committer:
- ahaas92
- Date:
- 2020-06-11
- Revision:
- 3:b029a3f73a9e
File content as of revision 3:b029a3f73a9e:
/*********************************************************************/ /* 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****/