![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
repo time
Dependencies: mbed MAX14720 MAX30205 USBDevice
Diff: HspGuiSourceV301/HSPGui/Presenter/RToRCalculator.cs
- 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; + } + } +}