repo time

Dependencies:   mbed MAX14720 MAX30205 USBDevice

Revision:
20:6d2af70c92ab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HspGuiSourceV301/HSPGui/Presenter/RToRCalculator.cs	Tue Apr 06 06:41:40 2021 +0000
@@ -0,0 +1,197 @@
+/*******************************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved.
+* 
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace HealthSensorPlatform.Presenter
+{
+    /// <summary>
+    /// R To R Calculator for referring R to R code values to ECG samples
+    /// </summary>
+    public class RToRCalculator
+    {
+        const int RToROffset = 3;
+
+        double masterClockFrequency;
+        int rToRDifferentialDelay;
+
+        int ecgDelay;
+        int rToRDelay;
+
+        double sampleRateRToR;
+        double sampleRateEcg;
+
+        double rToRTimeMilliSecond;
+
+        /// <summary>
+        /// Error difference between rounded R To R in ECG samples and actual calculated value. Error used
+        /// in calculation of next R To R in ECG samples point.
+        /// </summary>
+        double ecgSampleError;
+
+        /// <summary>
+        /// FMSTR clock frequency. Array index by FMSTR[1:0]
+        /// </summary>
+        double[] clockFreq = { 32768, 32000, 32000, 32768 * 640 / 656 }; // 31968.7804878 = 32768 * 640 / 65
+        /// <summary>
+        /// ECG decimation delay. Array indexed by FMSTR, ECG_RATE, ECG_DLFF (0 for disabled, 1 for enabled) 
+        /// </summary>
+        int[, ,] ecgDecimationDelay = new int[,,] { {{650, 1034}, {2922, 3690}, {3370, 4906}, {3370, 4906}}, 
+													{{650, 1034}, {2922, 3690}, {3370, 4906}, {3370, 4906}},
+													{{1242, 2202}, {1242, 2202}, {1242, 2202}, {1242, 2202}},
+													{{1242, 2202}, {1242, 2202}, {1242, 2202}, {1242, 2202}}
+                                                  };
+
+        /// <summary>
+        /// ECG sample rate look up based on FMSTR and ECG_RATE
+        /// </summary>
+        double[][] ecgSampleRates = new double[][]
+        {
+                new double[] {512, 256, 128, 128},
+                new double[] {500, 250, 125, 125},
+                new double[] {200, 200, 200, 200},
+                new double[] {199.8, 199.8, 199.8, 199.8} 
+        };
+
+        /// <summary>
+        /// ECG processing delay in FMSTR clocks
+        /// </summary>
+        public int EcgDecimationDelay
+        {
+            get
+            {
+                return ecgDelay;
+            }
+        }
+
+        /// <summary>
+        /// R To R path processing delay in FMSTR clocks
+        /// </summary>
+        public int RToRDelay
+        {
+            get
+            {
+                return rToRDelay;
+            }
+        }
+
+        /// <summary>
+        /// Last R To R detected time in millisecond from first ECG point
+        /// </summary>
+        public double RToRMilliSecond
+        {
+            get
+            {
+                return rToRTimeMilliSecond;
+            }
+        }
+        
+        /// <summary>
+        /// Constructor for R to R calculator
+        /// </summary>
+        /// <param name="masterClockFrequencyField">Value of FMSTR[1:0]</param>
+        /// <param name="sampleRateEcgField">Value of ECG_RATE[1:0]</param>
+        /// <param name="ecgDigitalLowPass">Value of ECG_DLF[1:0]</param>
+        /// <param name="rTorWindowField">Value of RTOR_WNDW[3:0]</param>
+        public RToRCalculator(int masterClockFrequencyField, int sampleRateEcgField, int ecgDigitalLowPass, int rTorWindowField)
+        {
+            masterClockFrequency = clockFreq[masterClockFrequencyField];
+            sampleRateRToR = masterClockFrequency / 256;
+            sampleRateEcg = ecgSampleRates[masterClockFrequencyField][sampleRateEcgField];
+
+            ecgDelay = ecgDecimationDelay[masterClockFrequencyField, sampleRateEcgField, ecgDigitalLowPass > 0 ? 1 : 0];
+            rToRDelay = 5376 + 3370 + 256 * rTorWindowField;
+
+            rToRDifferentialDelay = rToRDelay - ecgDelay;
+
+            rToRTimeMilliSecond = 0;
+        }
+
+        /// <summary>
+        /// R To R code to beats per minute
+        /// </summary>
+        /// <param name="rToRCode">R To R Code</param>
+        /// <returns></returns>
+        public double BeatsPerMinute(int rToRCode)
+        {
+            return 60 * 1000 / Millisecond(rToRCode);
+        }
+
+        /// <summary>
+        /// R To R code to millisecond interval
+        /// </summary>
+        /// <param name="rToRCode">R To R Code</param>
+        /// <returns></returns>
+        public double Millisecond(double rToRCode)
+        {
+            return rToRCode * 512.0 * 1000 / (2 * masterClockFrequency);
+        }
+
+        public double Corrected(int rToR, bool first)
+        {
+            if (first)
+                rToRTimeMilliSecond = Millisecond(rToR - rToRDifferentialDelay / 256.0);
+            else
+                rToRTimeMilliSecond += Millisecond(rToR);
+
+            return rToRTimeMilliSecond;
+        }
+
+        /// <summary>
+        /// R To R code converted to ECG points
+        /// </summary>
+        /// <param name="rToR">R To R code</param>
+        /// <param name="first">first R To R sample include the processing delay between the ECG and R To R processing path</param>
+        /// <returns></returns>
+        public int EcgPoints(int rToR, bool first)
+        {
+            double rToRInEcgSamples;
+            int rToRInEcgSamplesInt;
+
+            if (first)
+                rToRInEcgSamples = (rToR - rToRDifferentialDelay / 256.0) * (sampleRateEcg / sampleRateRToR) + RToROffset;
+            else
+                rToRInEcgSamples = rToR * (sampleRateEcg / sampleRateRToR) - ecgSampleError;
+
+            rToRInEcgSamplesInt = (int)(rToRInEcgSamples + 0.5);
+            ecgSampleError = rToRInEcgSamplesInt - rToRInEcgSamples;
+
+            return rToRInEcgSamplesInt;
+        }
+    }
+}