From ed05f0c64b58b3f8f4ac65a059a75a6d3d0a95e4 Mon Sep 17 00:00:00 2001
From: schneider <schneider@blinkenlichts.net>
Date: Fri, 3 May 2019 16:31:17 +0200
Subject: [PATCH] feat(test): Move ecg test to testapp

---
 testapp/.cproject                       | 107 +++++++++
 testapp/.gdbinit                        |   3 +
 testapp/.project                        |  26 +++
 testapp/.settings/language.settings.xml |  10 +
 testapp/MAX30003.h                      | 277 ++++++++++++++++++++++
 testapp/Makefile                        | 122 ++++++++++
 testapp/build_image                     |   5 +
 testapp/main.c                          | 298 ++++++++++++++++++++++++
 8 files changed, 848 insertions(+)
 create mode 100644 testapp/.cproject
 create mode 100644 testapp/.gdbinit
 create mode 100644 testapp/.project
 create mode 100644 testapp/.settings/language.settings.xml
 create mode 100644 testapp/MAX30003.h
 create mode 100644 testapp/Makefile
 create mode 100755 testapp/build_image
 create mode 100644 testapp/main.c

diff --git a/testapp/.cproject b/testapp/.cproject
new file mode 100644
index 00000000..6adc9947
--- /dev/null
+++ b/testapp/.cproject
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug">
+					<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962." name="/" resourcePath="">
+						<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.548125692" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1448195934" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.989348626" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.573934961" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.1195068176" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1035348629" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.31679983" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1676901946" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1729767352" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1708484008" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.178519983" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m3" valueType="enumerated"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.956545422" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1580514969" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1246670973" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1674926322" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.2051566192" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.408066731" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.1900584936" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.1096852527" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.937347953" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.1468247042" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1529750846" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
+							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.667765305" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.786533016" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
+							<builder arguments="ECLIPSE=1" buildPath="${workspace_loc:/Hello_World}" command="make" id="ilg.gnuarmeclipse.managedbuild.cross.builder.592880777" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1648672385" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1969112665" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
+								<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.507854261" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
+							</tool>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1576427906" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
+									<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.1576427906" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Firmware/MAX32665/Libraries/CMSIS/Device/Maxim/MAX32665/Include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Firmware/MAX32665/Libraries/MAX32665PeriphDriver/Include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Firmware/MAX32665/Libraries/Boards/EvKit_V1/Include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Firmware/MAX32665/Libraries/Boards/Include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Firmware/MAX32665/Libraries/CMSIS/Include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Toolchain/arm-none-eabi/include&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Toolchain/arm-none-eabi/include/sys&quot;"/>
+										<listOptionValue builtIn="false" value="&quot;${MAXIM_PATH}/Toolchain/lib/gcc/arm-none-eabi/6.3.1/include&quot;"/>
+									</option>
+								<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.68945223" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
+							</tool>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.794996645" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"/>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.675776866" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.185399645" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
+								<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.246156916" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.391142733" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.2099090970" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
+							</tool>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.399743328" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.822983655" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.1050446219" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.335976671" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.964898349" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.972868647" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.890608562" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.1669392057" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
+							</tool>
+							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.403251962" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
+								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.1919947275" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="Hello_World.ilg.gnuarmeclipse.managedbuild.cross.target.elf.737306620" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962;ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1576427906;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.68945223">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/Hello_World"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cproject>
diff --git a/testapp/.gdbinit b/testapp/.gdbinit
new file mode 100644
index 00000000..85b92cf7
--- /dev/null
+++ b/testapp/.gdbinit
@@ -0,0 +1,3 @@
+file build/max32665.elf
+target remote localhost:3333
+
diff --git a/testapp/.project b/testapp/.project
new file mode 100644
index 00000000..035be64a
--- /dev/null
+++ b/testapp/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Hello_World</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
diff --git a/testapp/.settings/language.settings.xml b/testapp/.settings/language.settings.xml
new file mode 100644
index 00000000..e5a16476
--- /dev/null
+++ b/testapp/.settings/language.settings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+    <configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1674944962" name="Debug">
+        <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+            <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+            <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+        </extension>
+    </configuration>
+</project>
diff --git a/testapp/MAX30003.h b/testapp/MAX30003.h
new file mode 100644
index 00000000..f0a54b9d
--- /dev/null
+++ b/testapp/MAX30003.h
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * 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.
+ *******************************************************************************
+ */
+
+
+#ifndef _MAX30003_H_
+#define _MAX30003_H_
+
+
+    ///MAX30003 Registers
+    enum Registers_e
+    {
+        NO_OP          = 0x00,
+        STATUS         = 0x01,
+        EN_INT         = 0x02,
+        EN_INT2        = 0x03,
+        MNGR_INT       = 0x04,
+        MNGR_DYN       = 0x05,
+        SW_RST         = 0x08,
+        SYNCH          = 0x09,
+        FIFO_RST       = 0x0A,
+        INFO           = 0x0F,
+        CNFG_GEN       = 0x10,
+        CNFG_ALL       = 0x12,
+        CNFG_EMUX      = 0x14,
+        CNFG_ECG       = 0x15,
+        CNFG_RTOR1     = 0x1D,
+        CNFG_RTOR2     = 0x1E,
+        ECG_FIFO_BURST = 0x20,
+        ECG_FIFO       = 0x21,
+        RTOR           = 0x25,
+        NO_OP2         = 0x7F
+    };
+
+    ///Status register bits
+    union Status_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct
+        {
+            uint32_t loff_nl    : 1;
+            uint32_t loff_nh    : 1;
+            uint32_t loff_pl    : 1;
+            uint32_t loff_ph    : 1;
+            uint32_t reserved1  : 4;
+            uint32_t pllint     : 1;
+            uint32_t samp       : 1;
+            uint32_t rrint      : 1;
+            uint32_t lonint     : 1;
+            uint32_t reserved2  : 8;
+            uint32_t dcloffint : 1;
+            uint32_t fstint     : 1;
+            uint32_t eovf       : 1;
+            uint32_t eint       : 1;
+            uint32_t reserved3  : 8;
+        }bits;
+    };
+
+    ///Enable Interrupt registers bits
+    union EnableInterrupts_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t intb_type    : 2;
+            uint32_t reserved1    : 6;
+            uint32_t en_pllint    : 1;
+            uint32_t en_samp      : 1;
+            uint32_t en_rrint     : 1;
+            uint32_t en_loint     : 1;
+            uint32_t reserved2    : 8;
+            uint32_t en_dcloffint : 1;
+            uint32_t en_fstint    : 1;
+            uint32_t en_eovf      : 1;
+            uint32_t en_eint      : 1;
+            uint32_t reserved3    : 8;
+        }bits;
+    };
+
+    ///Manage Interrupt register bits
+    union ManageInterrupts_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t samp_it   : 4;
+            uint32_t clr_samp  : 1;
+            uint32_t reserved1 : 1;
+            uint32_t clr_rrint : 2;
+            uint32_t clr_fast  : 1;
+            uint32_t reserved2 : 12;
+            uint32_t efit      : 5;
+            uint32_t reserved3 : 8;
+        }bits;
+    };
+
+    ///Manage Dynamic Modes register bits
+    union ManageDynamicModes_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t reserved1 : 16;
+            uint32_t fast_th   : 6;
+            uint32_t fast      : 2;
+            uint32_t reserved2 : 8;
+        }bits;
+    };
+
+    ///General Configuration bits
+    union GeneralConfiguration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t rbiasn     : 1;
+            uint32_t rbiasp     : 1;
+            uint32_t rbiasv     : 2;
+            uint32_t en_rbias   : 2;
+            uint32_t vth        : 2;
+            uint32_t imag       : 3;
+            uint32_t ipol       : 1;
+            uint32_t en_dcloff  : 2;
+            uint32_t reserved1  : 5;
+            uint32_t en_ecg     : 1;
+            uint32_t fmstr      : 2;
+            uint32_t en_ulp_lon : 2;
+            uint32_t reserved2  : 8;
+        }bits;
+    };
+
+    ///Cal Configuration bits
+    union CalConfiguration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t thigh     : 11;
+            uint32_t fifty     : 1;
+            uint32_t fcal      : 3;
+            uint32_t reserved1 : 5;
+            uint32_t vmag      : 1;
+            uint32_t vmode     : 1;
+            uint32_t en_vcal   : 1;
+            uint32_t reserved2 : 9;
+
+        }bits;
+    };
+
+    ///Mux Configuration bits
+    union MuxConfiguration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t reserved1 : 16;
+            uint32_t caln_sel  : 2;
+            uint32_t calp_sel  : 2;
+            uint32_t openn     : 1;
+            uint32_t openp     : 1;
+            uint32_t reserved2 : 1;
+            uint32_t pol       : 1;
+            uint32_t reserved3 : 8;
+        }bits;
+    };
+
+    ///ECG Configuration bits
+    union ECGConfiguration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t reserved1 : 12;
+            uint32_t dlpf      : 2;
+            uint32_t dhpf      : 1;
+            uint32_t reserved2 : 1;
+            uint32_t gain      : 2;
+            uint32_t reserved3 : 4;
+            uint32_t rate      : 2;
+            uint32_t reserved4 : 8;
+        }bits;
+    };
+
+    ///RtoR1 Configuration bits
+    union RtoR1Configuration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t reserved1 : 8;
+            uint32_t ptsf      : 4;
+            uint32_t pavg      : 2;
+            uint32_t reserved2 : 1;
+            uint32_t en_rtor   : 1;
+            uint32_t rgain     : 4;
+            uint32_t wndw      : 4;
+            uint32_t reserved3 : 8;
+        }bits;
+    };
+
+    ///RtoR2 Configuration bits
+    union RtoR2Configuration_u
+    {
+        ///Access all bits
+        uint32_t all;
+
+        ///Access individual bits
+        struct 
+        {
+            uint32_t reserved1 : 8;
+            uint32_t rhsf      : 3;
+            uint32_t reserved2 : 1;
+            uint32_t ravg      : 2;
+            uint32_t reserved3 : 2;
+            uint32_t hoff      : 6;
+            uint32_t reserved4 : 10;
+        }bits;
+    };
+
+#endif /* _MAX30003_H_ */
+
diff --git a/testapp/Makefile b/testapp/Makefile
new file mode 100644
index 00000000..f399063a
--- /dev/null
+++ b/testapp/Makefile
@@ -0,0 +1,122 @@
+################################################################################
+ # Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ #
+ # Permission is hereby granted, free of charge, to any person obtaining a
+ # copy of this software and associated documentation files (the "Software"),
+ # to deal in the Software without restriction, including without limitation
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ # and/or sell copies of the Software, and to permit persons to whom the
+ # Software is furnished to do so, subject to the following conditions:
+ #
+ # 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.
+ #
+ # $Date: 2018-09-28 18:22:39 +0000 (Fri, 28 Sep 2018) $ 
+ # $Revision: 38193 $
+ #
+ ###############################################################################
+
+# This is the name of the build output file
+ifeq "$(PROJECT)" ""
+PROJECT=max32665
+endif
+
+# Specify the target processor
+ifeq "$(TARGET)" ""
+TARGET=MAX32665
+endif
+
+# Create Target name variables
+TARGET_UC:=$(shell echo $(TARGET) | tr a-z A-Z)
+TARGET_LC:=$(shell echo $(TARGET) | tr A-Z a-z)
+
+# Select 'GCC' or 'IAR' compiler
+COMPILER=GCC
+
+# Specify the board used
+ifeq "$(BOARD)" ""
+BOARD=EvKit_V1
+endif
+
+# This is the path to the CMSIS root directory
+ifeq "$(MAXIM_PATH)" ""
+LIBS_DIR=../sdk/Libraries
+else
+LIBS_DIR=/$(subst \,/,$(subst :,,$(MAXIM_PATH))/Firmware/$(TARGET_UC)/Libraries)
+endif
+CMSIS_ROOT=$(LIBS_DIR)/CMSIS
+
+# Source files for this test (add path to VPATH below)
+SRCS  = main.c
+
+# Where to find source files for this test
+VPATH = .
+
+# Where to find header files for this test
+IPATH = .
+
+IPATH += ../lib/card10
+VPATH += ../lib/card10
+
+# Enable assertion checking for development
+PROJ_CFLAGS+=-DMXC_ASSERT_ENABLE
+
+# Specify the target revision to override default
+# "A2" in ASCII
+# TARGET_REV=0x4132
+
+# Use this variables to specify and alternate tool path
+#TOOL_DIR=/opt/gcc-arm-none-eabi-4_8-2013q4/bin
+
+# Use these variables to add project specific tool options
+#PROJ_CFLAGS+=--specs=nano.specs
+#PROJ_LDFLAGS+=--specs=nano.specs
+
+PROJ_CFLAGS+=-std=c99
+
+# Point this variable to a startup file to override the default file
+#STARTUPFILE=start.S
+
+# Override the default optimization level using this variable
+#MXC_OPTIMIZE_CFLAGS=-O1
+
+# Point this variable to a linker file to override the default file
+LINKERFILE=$(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/GCC/$(TARGET_LC)_app.ld
+
+################################################################################
+# Include external library makefiles here
+
+# Include the BSP
+BOARD_DIR=$(LIBS_DIR)/Boards/$(BOARD)
+include $(BOARD_DIR)/board.mk
+
+# Include the peripheral driver
+PERIPH_DRIVER_DIR=$(LIBS_DIR)/$(TARGET_UC)PeriphDriver
+include $(PERIPH_DRIVER_DIR)/periphdriver.mk
+
+################################################################################
+# Include the rules for building for this target. All other makefiles should be
+# included before this one.
+include $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/$(COMPILER)/$(TARGET_LC).mk
+
+# The rule to clean out all the build products.
+distclean: clean
+	$(MAKE) -C ${PERIPH_DRIVER_DIR} clean
diff --git a/testapp/build_image b/testapp/build_image
new file mode 100755
index 00000000..7119c5c5
--- /dev/null
+++ b/testapp/build_image
@@ -0,0 +1,5 @@
+make clean
+make
+make build/max32665.bin
+cp build/max32665.bin card10.bin
+python ../bootloader/crc_patch.py card10.bin
diff --git a/testapp/main.c b/testapp/main.c
new file mode 100644
index 00000000..fcde5494
--- /dev/null
+++ b/testapp/main.c
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * 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.
+ *
+ * $Date: 2018-09-04 22:13:32 +0000 (Tue, 04 Sep 2018) $
+ * $Revision: 37649 $
+ *
+ ******************************************************************************/
+
+/**
+ * @file    main.c
+ * @brief   Hello World!
+ * @details This example uses the UART to print to a terminal and flashes an LED.
+ */
+
+/***** Includes *****/
+#include <stdio.h>
+#include <stdint.h>
+#include "mxc_config.h"
+#include "led.h"
+#include "board.h"
+#include "tmr_utils.h"
+#include "i2c.h"
+#include "rtc.h"
+#include "spi.h"
+#include "MAX30003.h"
+
+/***** Definitions *****/
+
+#define I2C_DEVICE	    MXC_I2C0_BUS0
+
+#define SPI SPI0
+#define SPI_SPEED       10000000  // Bit Rate
+
+
+/***** Globals *****/
+
+/***** Functions *****/
+#if 0
+void I2C0_IRQHandler(void)
+{
+    I2C_Handler(I2C_DEVICE);
+    return;
+}
+#endif
+
+uint32_t ecg_read_reg(uint8_t reg)
+{
+    spi_req_t req;
+    uint8_t tx_data[] = {(reg << 1) | 1, 0, 0, 0};
+    uint8_t rx_data[] = {0, 0, 0, 0};
+    req.tx_data = tx_data;
+    req.rx_data = rx_data;
+    req.len = 4;
+    req.bits = 8;
+    req.width = SPI17Y_WIDTH_1;
+    req.ssel = 0;
+    req.deass = 1;
+    req.ssel_pol = SPI17Y_POL_LOW;
+    req.tx_num = 0;
+    req.rx_num = 0;
+
+    SPI_MasterTrans(SPI, &req);
+
+    return (rx_data[1] << 16) | (rx_data[2] << 8) | rx_data[3];
+}
+
+void ecg_write_reg(uint8_t reg, uint32_t data)
+{
+    printf("write %02x %06x\n", reg, data);
+    spi_req_t req;
+    uint8_t tx_data[] = {(reg << 1) | 0 , data >> 16, (data >> 8 ) & 0xFF, data & 0xFF};
+    uint8_t rx_data[] = {0, 0, 0, 0};
+    req.tx_data = tx_data;
+    req.rx_data = rx_data;
+    req.len = 4;
+    req.bits = 8;
+    req.width = SPI17Y_WIDTH_1;
+    req.ssel = 0;
+    req.deass = 1;
+    req.ssel_pol = SPI17Y_POL_LOW;
+    req.tx_num = 0;
+    req.rx_num = 0;
+
+    SPI_MasterTrans(SPI, &req);
+}
+
+void ecg_config(void)
+{
+    // Reset ECG to clear registers
+    ecg_write_reg(SW_RST , 0);
+
+    // General config register setting
+    union GeneralConfiguration_u CNFG_GEN_r;
+    CNFG_GEN_r.bits.en_ecg = 1;     // Enable ECG channel
+    CNFG_GEN_r.bits.rbiasn = 1;     // Enable resistive bias on negative input
+    CNFG_GEN_r.bits.rbiasp = 1;     // Enable resistive bias on positive input
+    CNFG_GEN_r.bits.en_rbias = 1;   // Enable resistive bias
+    CNFG_GEN_r.bits.imag = 2;       // Current magnitude = 10nA
+    CNFG_GEN_r.bits.en_dcloff = 1;  // Enable DC lead-off detection
+    ecg_write_reg(CNFG_GEN , CNFG_GEN_r.all);
+
+
+    // ECG Config register setting
+    union ECGConfiguration_u CNFG_ECG_r;
+    CNFG_ECG_r.bits.dlpf = 1;       // Digital LPF cutoff = 40Hz
+    CNFG_ECG_r.bits.dhpf = 1;       // Digital HPF cutoff = 0.5Hz
+    //CNFG_ECG_r.bits.gain = 3;       // ECG gain = 160V/V
+    CNFG_ECG_r.bits.gain = 0;
+    CNFG_ECG_r.bits.rate = 2;       // Sample rate = 128 sps
+    ecg_write_reg(CNFG_ECG , CNFG_ECG_r.all);
+
+
+    //R-to-R configuration
+    union RtoR1Configuration_u CNFG_RTOR_r;
+    CNFG_RTOR_r.bits.en_rtor = 1;           // Enable R-to-R detection
+    ecg_write_reg(CNFG_RTOR1 , CNFG_RTOR_r.all);
+
+
+    //Manage interrupts register setting
+    union ManageInterrupts_u MNG_INT_r;
+    MNG_INT_r.bits.efit = 0b00011;          // Assert EINT w/ 4 unread samples
+    MNG_INT_r.bits.clr_rrint = 0b01;        // Clear R-to-R on RTOR reg. read back
+    ecg_write_reg(MNGR_INT , MNG_INT_r.all);
+
+
+    //Enable interrupts register setting
+    union EnableInterrupts_u EN_INT_r;
+    EN_INT_r.all = 0;
+    EN_INT_r.bits.en_eint = 1;              // Enable EINT interrupt
+    EN_INT_r.bits.en_rrint = 0;             // Disable R-to-R interrupt
+    EN_INT_r.bits.intb_type = 3;            // Open-drain NMOS with internal pullup
+    ecg_write_reg(EN_INT , EN_INT_r.all);
+
+
+    //Dyanmic modes config
+    union ManageDynamicModes_u MNG_DYN_r;
+    MNG_DYN_r.bits.fast = 0;                // Fast recovery mode disabled
+    ecg_write_reg(MNGR_DYN , MNG_DYN_r.all);
+
+    // MUX Config
+    union MuxConfiguration_u CNFG_MUX_r;
+    CNFG_MUX_r.bits.openn = 0;          // Connect ECGN to AFE channel
+    CNFG_MUX_r.bits.openp = 0;          // Connect ECGP to AFE channel
+    ecg_write_reg(CNFG_EMUX , CNFG_MUX_r.all);
+
+    return;
+}
+
+// *****************************************************************************
+int main(void)
+{
+    //int count = 0;
+
+    printf("Hello World!\n");
+
+    //Setup the I2CM
+    I2C_Shutdown(I2C_DEVICE);
+    I2C_Init(I2C_DEVICE, I2C_FAST_MODE, NULL);
+ #if 0
+    NVIC_EnableIRQ(I2C0_IRQn); // Not sure if we actually need this when not doing async requests
+ #endif
+
+    uint8_t dummy[1] = {0};
+    // "7-bit addresses 0b0000xxx and 0b1111xxx are reserved"
+    for (int addr = 0x8; addr < 0x78; ++addr) {
+        // A 0 byte write does not seem to work so always send a single byte.
+        int res = I2C_MasterWrite(I2C_DEVICE, addr << 1, dummy, 1, 0);
+        if(res == 1) {
+            printf("Found (7 bit) address 0x%02x\n", addr);
+        }
+    }
+
+    // Enable 32 kHz output
+    //RTC_SquareWave(MXC_RTC, SQUARE_WAVE_ENABLED, F_32KHZ, NOISE_IMMUNE_MODE, NULL);
+
+    // Enable SPI
+    sys_cfg_spi_t spi17y_master_cfg;
+
+    spi17y_master_cfg.map = MAP_A;
+    spi17y_master_cfg.ss0 = Enable;
+    spi17y_master_cfg.ss1 = Disable;
+    spi17y_master_cfg.ss2 = Disable;
+
+    if (SPI_Init(SPI, 0, SPI_SPEED, spi17y_master_cfg) != 0) {
+        printf("Error configuring SPI\n");
+        while (1);
+    }
+
+    for(int i=0; i<0x20; i++) {
+        uint32_t val = ecg_read_reg(i);
+        printf("%02x: 0x%06x\n", i, val);
+    }
+
+    ecg_config();
+
+    for(int i=0; i<0x20; i++) {
+        uint32_t val = ecg_read_reg(i);
+        printf("%02x: 0x%06x\n", i, val);
+    }
+
+    while (0) {
+        LED_On(0);
+        TMR_Delay(MXC_TMR0, MSEC(500), 0);
+        LED_Off(0);
+        TMR_Delay(MXC_TMR0, MSEC(500), 0);
+        //printf("count = %d\n", count++);
+    }
+
+    ecg_write_reg(SYNCH, 0);
+
+    uint32_t ecgFIFO, readECGSamples, idx, ETAG[32], status;
+    int16_t ecgSample[32];
+    const int EINT_STATUS_MASK =  1 << 23;
+    const int FIFO_OVF_MASK =  0x7;
+    const int FIFO_VALID_SAMPLE_MASK =  0x0;
+    const int FIFO_FAST_SAMPLE_MASK =  0x1;
+    const int ETAG_BITS_MASK = 0x7;
+    uint8_t ecgFIFOIntFlag = 0;
+
+    const gpio_cfg_t interrupt_pin = {PORT_1, PIN_12, GPIO_FUNC_IN, GPIO_PAD_PULL_UP};
+    GPIO_Config(&interrupt_pin);
+
+    while(1) {
+
+#if 1
+        if(GPIO_InGet(&interrupt_pin) == 0) {
+            ecgFIFOIntFlag = 1;
+        }
+
+        // Read back ECG samples from the FIFO
+        if( ecgFIFOIntFlag ) {
+
+            ecgFIFOIntFlag = 0;
+
+            //printf("Int\n");
+            status = ecg_read_reg( STATUS );      // Read the STATUS register
+
+            // Check if EINT interrupt asserted
+            if ( ( status & EINT_STATUS_MASK ) == EINT_STATUS_MASK ) {
+
+                readECGSamples = 0;                        // Reset sample counter
+
+                do {
+                    ecgFIFO = ecg_read_reg(ECG_FIFO );       // Read FIFO
+                    ecgSample[readECGSamples] = ecgFIFO >> 8;                  // Isolate voltage data
+                    ETAG[readECGSamples] = ( ecgFIFO >> 3 ) & ETAG_BITS_MASK;  // Isolate ETAG
+                    readECGSamples++;                                          // Increment sample counter
+
+                // Check that sample is not last sample in FIFO
+                } while ( ETAG[readECGSamples-1] == FIFO_VALID_SAMPLE_MASK ||
+                          ETAG[readECGSamples-1] == FIFO_FAST_SAMPLE_MASK );
+
+                // Check if FIFO has overflowed
+                if( ETAG[readECGSamples - 1] == FIFO_OVF_MASK ){
+                    ecg_write_reg(FIFO_RST , 0); // Reset FIFO
+                    //printf("OV\n");
+                    LED_On(0);
+                    //rLed = 1;//notifies the user that an over flow occured
+                }
+
+                // Print results
+                for( idx = 0; idx < readECGSamples; idx++ ) {
+                    printf("%6d\r\n", ecgSample[idx]);
+                }
+
+            }
+        }
+#endif
+    }
+}
-- 
GitLab