repo time

Dependencies:   mbed MAX14720 MAX30205 USBDevice

Revision:
20:6d2af70c92ab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HspGuiSourceV301/HSPGui/Presenter/StreamPresenter.cs	Tue Apr 06 06:41:40 2021 +0000
@@ -0,0 +1,265 @@
+/*******************************************************************************
+* 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;
+
+using RPCSupport;
+using RPCSupport.Streaming;
+using HealthSensorPlatform.CustomControls;
+using HealthSensorPlatform.Model;
+using HealthSensorPlatform.View;
+
+namespace HealthSensorPlatform.Presenter
+{
+    public class StreamPresenter
+    {
+        const double NoData = -5000;
+        const int NoRToR = -1;
+
+        private RPCClient rpcClient;
+        private EcgView ecgView;
+        private IFormView formView;
+        private int rToRRaw = NoRToR;
+        private PaceData paceData;
+        private bool start = false;
+
+        public StreamPresenter()
+        {
+
+        }
+
+        public StreamPresenter(EcgView ecgView)
+        {
+            this.ecgView = ecgView;
+        }
+
+        public StreamPresenter(RPCClient rpcClient, EcgView ecgView, IFormView formView)
+        {
+            this.rpcClient = rpcClient;
+            this.ecgView = ecgView;
+            this.formView = formView;
+
+            ecgView.StreamingStartStop += new EventHandler<StreamingStartStopEventArgs>(OnStreamingStartStop);
+            rpcClient.streaming.PartialArrayIntAvailable += new EventHandler<PartialArrayIntAvailableEventArgs>(OnStreamData);
+        }
+
+        private void OnStreamingStartStop(object sender, StreamingStartStopEventArgs e)
+        {
+            start = e.state;
+
+            if (ecgView.Connected && !start) // Clear Interrupts on stream start and stop, start to prevent RPC Int Assignment freeze
+            {
+                rpcClient.MAX30001.WriteReg(0x02, 0x03); // Stop Interrupts
+                rpcClient.MAX30001.WriteReg(0x03, 0x03); // Stop Interrupts
+            }
+
+            formView.EcgLogFileItem(false);
+            formView.BioZLogFileItem(false);
+            formView.RtoRLogFileItem(false);
+            formView.PaceLogFileItem(false);
+        }
+
+        private void OnStreamData(object sender, PartialArrayIntAvailableEventArgs e)
+        {
+            int leadOffState;
+            if (start && e.array1.Length > 0) // Ignore events unless started (from flash logging)
+            {
+                leadOffState = e.array1[0];
+
+                switch(e.reportID)
+                {
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_DC:
+                        ecgView.SetDCLeadOff(leadOffState);
+                        break;
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_AC:
+                        ecgView.SetACLeadOff(leadOffState);
+                        break;
+                }
+
+                switch (e.reportID)
+                {
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_ECG:
+                        ProcessEcg(e.array1);
+                        break;
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_BIOZ:
+                        ProcessBioZ(e.array1);
+                        break;
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_PACE:
+                        ProcessPace(e.array1);
+                        break;
+                    case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_RTOR:
+                        rToRRaw = e.array1[0];
+                        ecgView.DisplayRToR(e.array1[0]);
+                        break;
+                }
+            }
+        }
+
+        void ProcessBioZ(int[] rawData)
+        {
+            BioZFifo[] bioZFifo;
+            double[] bioZImpedance;
+
+            bioZFifo = ConvertBioZ(rawData);
+
+            bioZImpedance = new double[bioZFifo.Length];
+            for (int i = 0; i < bioZFifo.Length; i++)
+            {
+                bioZImpedance[i] = bioZFifo[i].Data;
+            }
+            ecgView.DisplayBioZ(bioZImpedance);
+        }
+
+        public BioZFifo[] ConvertBioZ(int[] data)
+        {
+            BioZFifo[] impedence = new BioZFifo[data.Length];
+            EcgView.ChartInfo chartInfo = ecgView.BioZInfo;
+            int dataShift;
+
+            for (int i = 0; i < data.Length; i++)
+            {
+                dataShift = data[i] >> chartInfo.Shift;
+
+                // Two's Complement Conversions
+                if (dataShift > chartInfo.Threshold)
+                {
+                    dataShift -= chartInfo.Offset;
+                }
+
+                // 1.9734 = 1/2^19 * 1e-6
+                impedence[i].Data = dataShift * 1.9073486328125 /
+                    (chartInfo.Gain * ((chartInfo.CurrentGenerator == 0) ? 1 : chartInfo.CurrentGenerator));
+                impedence[i].BTag = data[i] & 0x07;
+            }
+
+            return impedence;
+        }
+
+        public double[] ProcessEcg(int[] rawData)
+        {
+            EcgFifo[] ecgFifo;
+            double[] ecgVoltage = new double[rawData.Length];
+            double[] rToRInterval = null;
+
+            // Pace File Log
+            string[] paceRegisterLog = new string[rawData.Length];
+
+            List<EcgView.PacePoint> pacePoints = new List<EcgView.PacePoint>();
+
+            ecgFifo = ConvertEcg(rawData); 
+
+            // ECG
+            for (int i = 0; i < ecgFifo.Length; i++)
+            {
+                ecgVoltage[i] = ecgFifo[i].Data;
+
+                if (ecgFifo[i].PTag != 0x07 && paceData != null) // Pace Event
+                {
+                    PaceData.PaceRegister paceRegister = paceData.PaceGroup(ecgFifo[i].PTag); // Register Group
+                    PaceData.PaceEdge[] paceEdges = paceRegister.Edge; // Pace Edge
+                    
+                    // Pace Charting Data
+                    int k = 0;
+                    PaceData.PaceEdge edge;
+                    do
+                    {
+                        edge = paceEdges[k];
+                        // Convert Pace into ECG samples
+                        // (Pace Raw / (2 * FMSTR )) / (1 / ECG Sample Rate) = Pace Raw * ECG Sample Rate / (2 * FMSTR)
+                        pacePoints.Add(new EcgView.PacePoint(i + (edge.Data * ecgView.SampleRateEcg / (2 * ecgView.MasterClockFrequency)), edge.Polarity));
+
+                        k++;
+                    }
+                    while (!(edge.Last == true || k >= 6));
+                }
+            }
+
+            // R to R
+            if (ecgView.EnableRToR)
+            {
+                rToRInterval = new double[rawData.Length];
+                for (int i = 0; i < rToRInterval.Length; i++)
+                {
+                    rToRInterval[i] = NoData;
+                }
+
+                if (rToRRaw > 0)
+                {
+                    rToRInterval[0] = ecgVoltage[0]; // Plot at height of ECG signal
+                    rToRRaw = NoRToR;
+                }
+            }
+
+            ecgView.DisplayEcg(ecgVoltage, pacePoints.ToArray(), rToRInterval);
+
+            return ecgVoltage;
+        }
+
+        public EcgFifo[] ConvertEcg(int[] data)
+        {
+            EcgFifo[] voltage = new EcgFifo[data.Length];
+            EcgView.ChartInfo chartInfo = ecgView.EcgInfo;
+            int dataShift;
+
+            for (int i = 0; i < data.Length; i++)
+            {
+                dataShift = data[i] >> chartInfo.Shift;
+
+                // Two's Complement Conversions
+                if (dataShift > chartInfo.Threshold)
+                {
+                    dataShift -= chartInfo.Offset;
+                }
+
+                voltage[i].Data = 1000 * 7.62939453125e-6 * dataShift / chartInfo.Gain;
+                voltage[i].PTag = data[i] & 0x07;
+                voltage[i].ETag = (data[i] >> 3) & 0x07;
+            }
+
+            return voltage;
+        }
+
+        public PaceData ProcessPace(int[] data)
+        {
+            paceData = new PaceData(data);
+
+            return paceData;
+        }
+
+    }
+}